Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2019-04-17 07:17:24 +0300
committerCampbell Barton <ideasman42@gmail.com>2019-04-17 07:21:24 +0300
commite12c08e8d170b7ca40f204a5b0423c23a9fbc2c1 (patch)
tree8cf3453d12edb177a218ef8009357518ec6cab6a /source/blender/editors/animation
parentb3dabc200a4b0399ec6b81f2ff2730d07b44fcaa (diff)
ClangFormat: apply to source, most of intern
Apply clang format as proposed in T53211. For details on usage and instructions for migrating branches without conflicts, see: https://wiki.blender.org/wiki/Tools/ClangFormat
Diffstat (limited to 'source/blender/editors/animation')
-rw-r--r--source/blender/editors/animation/CMakeLists.txt68
-rw-r--r--source/blender/editors/animation/anim_channels_defines.c6705
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c5042
-rw-r--r--source/blender/editors/animation/anim_deps.c623
-rw-r--r--source/blender/editors/animation/anim_draw.c986
-rw-r--r--source/blender/editors/animation/anim_filter.c5702
-rw-r--r--source/blender/editors/animation/anim_intern.h3
-rw-r--r--source/blender/editors/animation/anim_ipo_utils.c322
-rw-r--r--source/blender/editors/animation/anim_markers.c2156
-rw-r--r--source/blender/editors/animation/anim_motion_paths.c483
-rw-r--r--source/blender/editors/animation/anim_ops.c683
-rw-r--r--source/blender/editors/animation/drivers.c1788
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c1495
-rw-r--r--source/blender/editors/animation/keyframes_draw.c1681
-rw-r--r--source/blender/editors/animation/keyframes_edit.c1808
-rw-r--r--source/blender/editors/animation/keyframes_general.c1678
-rw-r--r--source/blender/editors/animation/keyframing.c4648
-rw-r--r--source/blender/editors/animation/keyingsets.c1522
18 files changed, 19292 insertions, 18101 deletions
diff --git a/source/blender/editors/animation/CMakeLists.txt b/source/blender/editors/animation/CMakeLists.txt
index ea37aab69ea..b67298a6df6 100644
--- a/source/blender/editors/animation/CMakeLists.txt
+++ b/source/blender/editors/animation/CMakeLists.txt
@@ -16,56 +16,56 @@
# ***** END GPL LICENSE BLOCK *****
set(INC
- ../include
- ../../blenkernel
- ../../blenlib
- ../../blentranslation
- ../../depsgraph
- ../../gpu
- ../../makesdna
- ../../makesrna
- ../../windowmanager
- ../../../../intern/clog
- ../../../../intern/guardedalloc
- ../../../../intern/glew-mx
+ ../include
+ ../../blenkernel
+ ../../blenlib
+ ../../blentranslation
+ ../../depsgraph
+ ../../gpu
+ ../../makesdna
+ ../../makesrna
+ ../../windowmanager
+ ../../../../intern/clog
+ ../../../../intern/guardedalloc
+ ../../../../intern/glew-mx
)
set(INC_SYS
- ${GLEW_INCLUDE_PATH}
+ ${GLEW_INCLUDE_PATH}
)
set(SRC
- anim_channels_defines.c
- anim_channels_edit.c
- anim_deps.c
- anim_draw.c
- anim_filter.c
- anim_ipo_utils.c
- anim_markers.c
- anim_motion_paths.c
- anim_ops.c
- drivers.c
- fmodifier_ui.c
- keyframes_draw.c
- keyframes_edit.c
- keyframes_general.c
- keyframing.c
- keyingsets.c
+ anim_channels_defines.c
+ anim_channels_edit.c
+ anim_deps.c
+ anim_draw.c
+ anim_filter.c
+ anim_ipo_utils.c
+ anim_markers.c
+ anim_motion_paths.c
+ anim_ops.c
+ drivers.c
+ fmodifier_ui.c
+ keyframes_draw.c
+ keyframes_edit.c
+ keyframes_general.c
+ keyframing.c
+ keyingsets.c
- anim_intern.h
+ anim_intern.h
)
set(LIB
- bf_blenkernel
- bf_blenlib
+ bf_blenkernel
+ bf_blenlib
)
if(WITH_INTERNATIONAL)
- add_definitions(-DWITH_INTERNATIONAL)
+ add_definitions(-DWITH_INTERNATIONAL)
endif()
if(WITH_PYTHON)
- add_definitions(-DWITH_PYTHON)
+ add_definitions(-DWITH_PYTHON)
endif()
add_definitions(${GL_DEFINITIONS})
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c
index daa2cda2e1b..78c17ac7015 100644
--- a/source/blender/editors/animation/anim_channels_defines.c
+++ b/source/blender/editors/animation/anim_channels_defines.c
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
#include <stdio.h>
#include "MEM_guardedalloc.h"
@@ -83,10 +82,10 @@
// XXX constant defines to be moved elsewhere?
/* extra padding for lengths (to go under scrollers) */
-#define EXTRA_SCROLL_PAD 100.0f
+#define EXTRA_SCROLL_PAD 100.0f
/* size of indent steps */
-#define INDENT_STEP_SIZE (0.35f * U.widget_unit)
+#define INDENT_STEP_SIZE (0.35f * U.widget_unit)
/* size of string buffers used for animation channel displayed names */
#define ANIM_CHAN_NAME_SIZE 256
@@ -100,163 +99,175 @@
/* Draw Backdrop ---------------------------------- */
/* get backdrop color for top-level widgets (Scene and Object only) */
-static void acf_generic_root_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3])
+static void acf_generic_root_color(bAnimContext *UNUSED(ac),
+ bAnimListElem *UNUSED(ale),
+ float r_color[3])
{
- /* darker blue for top-level widgets */
- UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELOB, r_color);
+ /* darker blue for top-level widgets */
+ UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELOB, r_color);
}
/* backdrop for top-level widgets (Scene and Object only) */
-static void acf_generic_root_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
+static void acf_generic_root_backdrop(bAnimContext *ac,
+ bAnimListElem *ale,
+ float yminc,
+ float ymaxc)
{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- View2D *v2d = &ac->ar->v2d;
- short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
- short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
- float color[3];
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ View2D *v2d = &ac->ar->v2d;
+ short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
+ short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+ float color[3];
- /* set backdrop drawing color */
- acf->get_backdrop_color(ac, ale, color);
+ /* set backdrop drawing color */
+ acf->get_backdrop_color(ac, ale, color);
- /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
- UI_draw_roundbox_corner_set((expanded) ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
- UI_draw_roundbox_3fvAlpha(true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
+ /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
+ UI_draw_roundbox_corner_set((expanded) ? UI_CNR_TOP_LEFT :
+ (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
+ UI_draw_roundbox_3fvAlpha(
+ true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
}
-
/* get backdrop color for data expanders under top-level Scene/Object */
-static void acf_generic_dataexpand_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3])
+static void acf_generic_dataexpand_color(bAnimContext *UNUSED(ac),
+ bAnimListElem *UNUSED(ale),
+ float r_color[3])
{
- /* lighter color than top-level widget */
- UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELSUBOB, r_color);
+ /* lighter color than top-level widget */
+ UI_GetThemeColor3fv(TH_DOPESHEET_CHANNELSUBOB, r_color);
}
/* backdrop for data expanders under top-level Scene/Object */
-static void acf_generic_dataexpand_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
+static void acf_generic_dataexpand_backdrop(bAnimContext *ac,
+ bAnimListElem *ale,
+ float yminc,
+ float ymaxc)
{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- View2D *v2d = &ac->ar->v2d;
- short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
- float color[3];
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ View2D *v2d = &ac->ar->v2d;
+ short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+ float color[3];
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- /* set backdrop drawing color */
- acf->get_backdrop_color(ac, ale, color);
+ /* set backdrop drawing color */
+ acf->get_backdrop_color(ac, ale, color);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor3fv(color);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3fv(color);
- /* no rounded corner - just rectangular box */
- immRectf(pos, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
+ /* no rounded corner - just rectangular box */
+ immRectf(pos, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
- immUnbindProgram();
+ immUnbindProgram();
}
/* helper method to test if group colors should be drawn */
static bool acf_show_channel_colors(bAnimContext *ac)
{
- bool showGroupColors = false;
+ bool showGroupColors = false;
- if (ac->sl) {
- switch (ac->spacetype) {
- case SPACE_ACTION:
- {
- SpaceAction *saction = (SpaceAction *)ac->sl;
- showGroupColors = !(saction->flag & SACTION_NODRAWGCOLORS);
+ if (ac->sl) {
+ switch (ac->spacetype) {
+ case SPACE_ACTION: {
+ SpaceAction *saction = (SpaceAction *)ac->sl;
+ showGroupColors = !(saction->flag & SACTION_NODRAWGCOLORS);
- break;
- }
- case SPACE_GRAPH:
- {
- SpaceGraph *sipo = (SpaceGraph *)ac->sl;
- showGroupColors = !(sipo->flag & SIPO_NODRAWGCOLORS);
+ break;
+ }
+ case SPACE_GRAPH: {
+ SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ showGroupColors = !(sipo->flag & SIPO_NODRAWGCOLORS);
- break;
- }
- }
- }
+ break;
+ }
+ }
+ }
- return showGroupColors;
+ return showGroupColors;
}
/* get backdrop color for generic channels */
static void acf_generic_channel_color(bAnimContext *ac, bAnimListElem *ale, float r_color[3])
{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- bActionGroup *grp = NULL;
- short indent = (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0;
- bool showGroupColors = acf_show_channel_colors(ac);
-
- if (ale->type == ANIMTYPE_FCURVE) {
- FCurve *fcu = (FCurve *)ale->data;
- grp = fcu->grp;
- }
-
- /* set color for normal channels
- * - use 3 shades of color group/standard color for 3 indention level
- * - only use group colors if allowed to, and if actually feasible
- */
- if (showGroupColors && (grp) && (grp->customCol)) {
- unsigned char cp[3];
-
- if (indent == 2) {
- copy_v3_v3_char((char *)cp, grp->cs.solid);
- }
- else if (indent == 1) {
- copy_v3_v3_char((char *)cp, grp->cs.select);
- }
- else {
- copy_v3_v3_char((char *)cp, grp->cs.active);
- }
-
- /* copy the colors over, transforming from bytes to floats */
- rgb_uchar_to_float(r_color, cp);
- }
- else {
- // FIXME: what happens when the indention is 1 greater than what it should be (due to grouping)?
- int colOfs = 10 - 10 * indent;
- UI_GetThemeColorShade3fv(TH_SHADE2, colOfs, r_color);
- }
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ bActionGroup *grp = NULL;
+ short indent = (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0;
+ bool showGroupColors = acf_show_channel_colors(ac);
+
+ if (ale->type == ANIMTYPE_FCURVE) {
+ FCurve *fcu = (FCurve *)ale->data;
+ grp = fcu->grp;
+ }
+
+ /* set color for normal channels
+ * - use 3 shades of color group/standard color for 3 indention level
+ * - only use group colors if allowed to, and if actually feasible
+ */
+ if (showGroupColors && (grp) && (grp->customCol)) {
+ unsigned char cp[3];
+
+ if (indent == 2) {
+ copy_v3_v3_char((char *)cp, grp->cs.solid);
+ }
+ else if (indent == 1) {
+ copy_v3_v3_char((char *)cp, grp->cs.select);
+ }
+ else {
+ copy_v3_v3_char((char *)cp, grp->cs.active);
+ }
+
+ /* copy the colors over, transforming from bytes to floats */
+ rgb_uchar_to_float(r_color, cp);
+ }
+ else {
+ // FIXME: what happens when the indention is 1 greater than what it should be (due to grouping)?
+ int colOfs = 10 - 10 * indent;
+ UI_GetThemeColorShade3fv(TH_SHADE2, colOfs, r_color);
+ }
}
/* get backdrop color for grease pencil channels */
static void acf_gpencil_channel_color(bAnimContext *ac, bAnimListElem *ale, float r_color[3])
{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- short indent = (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0;
- bool showGroupColors = acf_show_channel_colors(ac);
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ short indent = (acf->get_indent_level) ? acf->get_indent_level(ac, ale) : 0;
+ bool showGroupColors = acf_show_channel_colors(ac);
- if ((showGroupColors) && (ale->type == ANIMTYPE_GPLAYER)) {
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
- copy_v3_v3(r_color, gpl->color);
- }
- else {
- int colOfs = 10 - 10 * indent;
- UI_GetThemeColorShade3fv(TH_SHADE2, colOfs, r_color);
- }
+ if ((showGroupColors) && (ale->type == ANIMTYPE_GPLAYER)) {
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+ copy_v3_v3(r_color, gpl->color);
+ }
+ else {
+ int colOfs = 10 - 10 * indent;
+ UI_GetThemeColorShade3fv(TH_SHADE2, colOfs, r_color);
+ }
}
/* backdrop for generic channels */
-static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
+static void acf_generic_channel_backdrop(bAnimContext *ac,
+ bAnimListElem *ale,
+ float yminc,
+ float ymaxc)
{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- View2D *v2d = &ac->ar->v2d;
- short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
- float color[3];
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ View2D *v2d = &ac->ar->v2d;
+ short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+ float color[3];
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- /* set backdrop drawing color */
- acf->get_backdrop_color(ac, ale, color);
+ /* set backdrop drawing color */
+ acf->get_backdrop_color(ac, ale, color);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformColor3fv(color);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformColor3fv(color);
- /* no rounded corners - just rectangular box */
- immRectf(pos, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
+ /* no rounded corners - just rectangular box */
+ immRectf(pos, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
- immUnbindProgram();
+ immUnbindProgram();
}
/* Indention + Offset ------------------------------------------- */
@@ -264,99 +275,99 @@ static void acf_generic_channel_backdrop(bAnimContext *ac, bAnimListElem *ale, f
/* indention level is always the value in the name */
static short acf_generic_indention_0(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
{
- return 0;
+ return 0;
}
static short acf_generic_indention_1(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
{
- return 1;
+ return 1;
}
-#if 0 // XXX not used
+#if 0 // XXX not used
static short acf_generic_indention_2(bAnimContext *ac, bAnimListElem *ale)
{
- return 2;
+ return 2;
}
#endif
/* indention which varies with the grouping status */
static short acf_generic_indention_flexible(bAnimContext *UNUSED(ac), bAnimListElem *ale)
{
- short indent = 0;
+ short indent = 0;
- /* grouped F-Curves need extra level of indention */
- if (ale->type == ANIMTYPE_FCURVE) {
- FCurve *fcu = (FCurve *)ale->data;
+ /* grouped F-Curves need extra level of indention */
+ if (ale->type == ANIMTYPE_FCURVE) {
+ FCurve *fcu = (FCurve *)ale->data;
- // TODO: we need some way of specifying that the indention color should be one less...
- if (fcu->grp)
- indent++;
- }
+ // TODO: we need some way of specifying that the indention color should be one less...
+ if (fcu->grp)
+ indent++;
+ }
- /* no indention */
- return indent;
+ /* no indention */
+ return indent;
}
/* basic offset for channels derived from indention */
static short acf_generic_basic_offset(bAnimContext *ac, bAnimListElem *ale)
{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- if (acf && acf->get_indent_level)
- return acf->get_indent_level(ac, ale) * INDENT_STEP_SIZE;
- else
- return 0;
+ if (acf && acf->get_indent_level)
+ return acf->get_indent_level(ac, ale) * INDENT_STEP_SIZE;
+ else
+ return 0;
}
/* offset based on nodetree type */
static short acf_nodetree_rootType_offset(bNodeTree *ntree)
{
- if (ntree) {
- switch (ntree->type) {
- case NTREE_SHADER:
- /* 1 additional level (i.e. is indented one level in from material,
- * so shift all right by one step)
- */
- return INDENT_STEP_SIZE;
+ if (ntree) {
+ switch (ntree->type) {
+ case NTREE_SHADER:
+ /* 1 additional level (i.e. is indented one level in from material,
+ * so shift all right by one step)
+ */
+ return INDENT_STEP_SIZE;
- case NTREE_COMPOSIT:
- /* no additional levels needed */
- return 0;
+ case NTREE_COMPOSIT:
+ /* no additional levels needed */
+ return 0;
- case NTREE_TEXTURE:
- /* 2 additional levels */
- return INDENT_STEP_SIZE * 2;
- }
- }
+ case NTREE_TEXTURE:
+ /* 2 additional levels */
+ return INDENT_STEP_SIZE * 2;
+ }
+ }
- /* unknown */
- return 0;
+ /* unknown */
+ return 0;
}
/* offset for groups + grouped entities */
static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale)
{
- short offset = acf_generic_basic_offset(ac, ale);
+ short offset = acf_generic_basic_offset(ac, ale);
- if (ale->id) {
- /* texture animdata */
- if (GS(ale->id->name) == ID_TE) {
- offset += U.widget_unit;
- }
- /* materials and particles animdata */
- else if (ELEM(GS(ale->id->name), ID_MA, ID_PA))
- offset += (short)(0.7f * U.widget_unit);
+ if (ale->id) {
+ /* texture animdata */
+ if (GS(ale->id->name) == ID_TE) {
+ offset += U.widget_unit;
+ }
+ /* materials and particles animdata */
+ else if (ELEM(GS(ale->id->name), ID_MA, ID_PA))
+ offset += (short)(0.7f * U.widget_unit);
- /* if not in Action Editor mode, action-groups (and their children) must carry some offset too... */
- else if (ac->datatype != ANIMCONT_ACTION)
- offset += (short)(0.7f * U.widget_unit);
+ /* if not in Action Editor mode, action-groups (and their children) must carry some offset too... */
+ else if (ac->datatype != ANIMCONT_ACTION)
+ offset += (short)(0.7f * U.widget_unit);
- /* nodetree animdata */
- if (GS(ale->id->name) == ID_NT) {
- offset += acf_nodetree_rootType_offset((bNodeTree *)ale->id);
- }
- }
+ /* nodetree animdata */
+ if (GS(ale->id->name) == ID_NT) {
+ offset += acf_nodetree_rootType_offset((bNodeTree *)ale->id);
+ }
+ }
- /* offset is just the normal type - i.e. based on indention */
- return offset;
+ /* offset is just the normal type - i.e. based on indention */
+ return offset;
}
/* Name ------------------------------------------- */
@@ -364,31 +375,30 @@ static short acf_generic_group_offset(bAnimContext *ac, bAnimListElem *ale)
/* name for ID block entries */
static void acf_generic_idblock_name(bAnimListElem *ale, char *name)
{
- ID *id = (ID *)ale->data; /* data pointed to should be an ID block */
+ ID *id = (ID *)ale->data; /* data pointed to should be an ID block */
- /* just copy the name... */
- if (id && name)
- BLI_strncpy(name, id->name + 2, ANIM_CHAN_NAME_SIZE);
+ /* just copy the name... */
+ if (id && name)
+ BLI_strncpy(name, id->name + 2, ANIM_CHAN_NAME_SIZE);
}
/* name property for ID block entries */
static bool acf_generic_idblock_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
{
- RNA_id_pointer_create(ale->data, ptr);
- *prop = RNA_struct_name_property(ptr->type);
+ RNA_id_pointer_create(ale->data, ptr);
+ *prop = RNA_struct_name_property(ptr->type);
- return (*prop != NULL);
+ return (*prop != NULL);
}
-
/* name property for ID block entries which are just subheading "fillers" */
static bool acf_generic_idfill_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
{
- /* actual ID we're representing is stored in ale->data not ale->id, as id gives the owner */
- RNA_id_pointer_create(ale->data, ptr);
- *prop = RNA_struct_name_property(ptr->type);
+ /* actual ID we're representing is stored in ale->data not ale->id, as id gives the owner */
+ RNA_id_pointer_create(ale->data, ptr);
+ *prop = RNA_struct_name_property(ptr->type);
- return (*prop != NULL);
+ return (*prop != NULL);
}
/* Settings ------------------------------------------- */
@@ -397,33 +407,35 @@ static bool acf_generic_idfill_name_prop(bAnimListElem *ale, PointerRNA *ptr, Pr
/* channel type has no settings */
static bool acf_generic_none_setting_valid(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
{
- return false;
+ return false;
}
#endif
/* check if some setting exists for this object-based data-expander (datablock only) */
-static bool acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
+static bool acf_generic_dataexpand_setting_valid(bAnimContext *ac,
+ bAnimListElem *UNUSED(ale),
+ eAnimChannel_Settings setting)
{
- switch (setting) {
- /* expand is always supported */
- case ACHANNEL_SETTING_EXPAND:
- return true;
+ switch (setting) {
+ /* expand is always supported */
+ case ACHANNEL_SETTING_EXPAND:
+ return true;
- /* mute is only supported for NLA */
- case ACHANNEL_SETTING_MUTE:
- return ((ac) && (ac->spacetype == SPACE_NLA));
+ /* mute is only supported for NLA */
+ case ACHANNEL_SETTING_MUTE:
+ return ((ac) && (ac->spacetype == SPACE_NLA));
- /* select is ok for most "ds*" channels (e.g. dsmat) */
- case ACHANNEL_SETTING_SELECT:
- return true;
+ /* select is ok for most "ds*" channels (e.g. dsmat) */
+ case ACHANNEL_SETTING_SELECT:
+ return true;
- case ACHANNEL_SETTING_ALWAYS_VISIBLE:
- return true;
+ case ACHANNEL_SETTING_ALWAYS_VISIBLE:
+ return true;
- /* other flags are never supported */
- default:
- return false;
- }
+ /* other flags are never supported */
+ default:
+ return false;
+ }
}
/* *********************************************** */
@@ -432,105 +444,113 @@ static bool acf_generic_dataexpand_setting_valid(bAnimContext *ac, bAnimListElem
/* Animation Summary ----------------------------------- */
/* get backdrop color for summary widget */
-static void acf_summary_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3])
+static void acf_summary_color(bAnimContext *UNUSED(ac),
+ bAnimListElem *UNUSED(ale),
+ float r_color[3])
{
- /* reddish color - same as the 'action' line in NLA */
- UI_GetThemeColor3fv(TH_ANIM_ACTIVE, r_color);
+ /* reddish color - same as the 'action' line in NLA */
+ UI_GetThemeColor3fv(TH_ANIM_ACTIVE, r_color);
}
/* backdrop for summary widget */
static void acf_summary_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- View2D *v2d = &ac->ar->v2d;
- float color[3];
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ View2D *v2d = &ac->ar->v2d;
+ float color[3];
- /* set backdrop drawing color */
- acf->get_backdrop_color(ac, ale, color);
+ /* set backdrop drawing color */
+ acf->get_backdrop_color(ac, ale, color);
- /* rounded corners on LHS only
- * - top and bottom
- * - special hack: make the top a bit higher, since we are first...
- */
- UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
- UI_draw_roundbox_3fvAlpha(true, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
+ /* rounded corners on LHS only
+ * - top and bottom
+ * - special hack: make the top a bit higher, since we are first...
+ */
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT);
+ UI_draw_roundbox_3fvAlpha(
+ true, 0, yminc - 2, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
}
/* name for summary entries */
static void acf_summary_name(bAnimListElem *UNUSED(ale), char *name)
{
- if (name)
- BLI_strncpy(name, IFACE_("Dope Sheet Summary"), ANIM_CHAN_NAME_SIZE);
+ if (name)
+ BLI_strncpy(name, IFACE_("Dope Sheet Summary"), ANIM_CHAN_NAME_SIZE);
}
// FIXME: this is really a temp icon I think
static int acf_summary_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_BORDERMOVE;
+ return ICON_BORDERMOVE;
}
/* check if some setting exists for this channel */
-static bool acf_summary_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
+static bool acf_summary_setting_valid(bAnimContext *UNUSED(ac),
+ bAnimListElem *UNUSED(ale),
+ eAnimChannel_Settings setting)
{
- /* only expanded is supported, as it is used for hiding all stuff which the summary covers */
- return (setting == ACHANNEL_SETTING_EXPAND);
+ /* only expanded is supported, as it is used for hiding all stuff which the summary covers */
+ return (setting == ACHANNEL_SETTING_EXPAND);
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_summary_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
-{
- if (setting == ACHANNEL_SETTING_EXPAND) {
- /* expanded */
- *neg = true;
- return ADS_FLAG_SUMMARY_COLLAPSED;
- }
- else {
- /* unsupported */
- *neg = false;
- return 0;
- }
+static int acf_summary_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
+{
+ if (setting == ACHANNEL_SETTING_EXPAND) {
+ /* expanded */
+ *neg = true;
+ return ADS_FLAG_SUMMARY_COLLAPSED;
+ }
+ else {
+ /* unsupported */
+ *neg = false;
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_summary_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
+static void *acf_summary_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings setting,
+ short *type)
{
- bAnimContext *ac = (bAnimContext *)ale->data;
+ bAnimContext *ac = (bAnimContext *)ale->data;
- /* if data is valid, return pointer to active dopesheet's relevant flag
- * - this is restricted to DopeSheet/Action Editor only
- */
- if ((ac->sl) && (ac->spacetype == SPACE_ACTION) && (setting == ACHANNEL_SETTING_EXPAND)) {
- SpaceAction *saction = (SpaceAction *)ac->sl;
- bDopeSheet *ads = &saction->ads;
+ /* if data is valid, return pointer to active dopesheet's relevant flag
+ * - this is restricted to DopeSheet/Action Editor only
+ */
+ if ((ac->sl) && (ac->spacetype == SPACE_ACTION) && (setting == ACHANNEL_SETTING_EXPAND)) {
+ SpaceAction *saction = (SpaceAction *)ac->sl;
+ bDopeSheet *ads = &saction->ads;
- /* return pointer to DopeSheet's flag */
- return GET_ACF_FLAG_PTR(ads->flag, type);
- }
- else {
- /* can't return anything useful - unsupported */
- *type = 0;
- return NULL;
- }
+ /* return pointer to DopeSheet's flag */
+ return GET_ACF_FLAG_PTR(ads->flag, type);
+ }
+ else {
+ /* can't return anything useful - unsupported */
+ *type = 0;
+ return NULL;
+ }
}
/* all animation summary (DopeSheet only) type define */
-static bAnimChannelType ACF_SUMMARY =
-{
- "Summary", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_summary_color, /* backdrop color */
- acf_summary_backdrop, /* backdrop */
- acf_generic_indention_0, /* indent level */
- NULL, /* offset */
-
- acf_summary_name, /* name */
- NULL, /* name prop */
- acf_summary_icon, /* icon */
-
- acf_summary_setting_valid, /* has setting */
- acf_summary_setting_flag, /* flag for setting */
- acf_summary_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_SUMMARY = {
+ "Summary", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_summary_color, /* backdrop color */
+ acf_summary_backdrop, /* backdrop */
+ acf_generic_indention_0, /* indent level */
+ NULL, /* offset */
+
+ acf_summary_name, /* name */
+ NULL, /* name prop */
+ acf_summary_icon, /* icon */
+
+ acf_summary_setting_valid, /* has setting */
+ acf_summary_setting_flag, /* flag for setting */
+ acf_summary_setting_ptr, /* pointer for setting */
};
/* Scene ------------------------------------------- */
@@ -538,269 +558,275 @@ static bAnimChannelType ACF_SUMMARY =
// TODO: just get this from RNA?
static int acf_scene_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_SCENE_DATA;
+ return ICON_SCENE_DATA;
}
/* check if some setting exists for this channel */
-static bool acf_scene_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
+static bool acf_scene_setting_valid(bAnimContext *ac,
+ bAnimListElem *UNUSED(ale),
+ eAnimChannel_Settings setting)
{
- switch (setting) {
- /* muted only in NLA */
- case ACHANNEL_SETTING_MUTE:
- return ((ac) && (ac->spacetype == SPACE_NLA));
+ switch (setting) {
+ /* muted only in NLA */
+ case ACHANNEL_SETTING_MUTE:
+ return ((ac) && (ac->spacetype == SPACE_NLA));
- /* visible only in Graph Editor */
- case ACHANNEL_SETTING_VISIBLE:
- return ((ac) && (ac->spacetype == SPACE_GRAPH));
+ /* visible only in Graph Editor */
+ case ACHANNEL_SETTING_VISIBLE:
+ return ((ac) && (ac->spacetype == SPACE_GRAPH));
- /* only select and expand supported otherwise */
- case ACHANNEL_SETTING_SELECT:
- case ACHANNEL_SETTING_EXPAND:
- return true;
+ /* only select and expand supported otherwise */
+ case ACHANNEL_SETTING_SELECT:
+ case ACHANNEL_SETTING_EXPAND:
+ return true;
- case ACHANNEL_SETTING_ALWAYS_VISIBLE:
- return false;
+ case ACHANNEL_SETTING_ALWAYS_VISIBLE:
+ return false;
- default:
- return false;
- }
+ default:
+ return false;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_scene_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_scene_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- return SCE_DS_SELECTED;
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return SCE_DS_SELECTED;
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- *neg = true;
- return SCE_DS_COLLAPSED;
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ *neg = true;
+ return SCE_DS_COLLAPSED;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
static void *acf_scene_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- Scene *scene = (Scene *)ale->data;
+ Scene *scene = (Scene *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- return GET_ACF_FLAG_PTR(scene->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return GET_ACF_FLAG_PTR(scene->flag, type);
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(scene->flag, type);
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(scene->flag, type);
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (scene->adt)
- return GET_ACF_FLAG_PTR(scene->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (scene->adt)
+ return GET_ACF_FLAG_PTR(scene->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* scene type define */
-static bAnimChannelType ACF_SCENE =
-{
- "Scene", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_root_color, /* backdrop color */
- acf_generic_root_backdrop, /* backdrop */
- acf_generic_indention_0, /* indent level */
- NULL, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_scene_icon, /* icon */
-
- acf_scene_setting_valid, /* has setting */
- acf_scene_setting_flag, /* flag for setting */
- acf_scene_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_SCENE = {
+ "Scene", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_root_color, /* backdrop color */
+ acf_generic_root_backdrop, /* backdrop */
+ acf_generic_indention_0, /* indent level */
+ NULL, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_scene_icon, /* icon */
+
+ acf_scene_setting_valid, /* has setting */
+ acf_scene_setting_flag, /* flag for setting */
+ acf_scene_setting_ptr, /* pointer for setting */
};
/* Object ------------------------------------------- */
static int acf_object_icon(bAnimListElem *ale)
{
- Base *base = (Base *)ale->data;
- Object *ob = base->object;
-
- /* icon depends on object-type */
- switch (ob->type) {
- case OB_LAMP:
- return ICON_OUTLINER_OB_LIGHT;
- case OB_MESH:
- return ICON_OUTLINER_OB_MESH;
- case OB_CAMERA:
- return ICON_OUTLINER_OB_CAMERA;
- case OB_CURVE:
- return ICON_OUTLINER_OB_CURVE;
- case OB_MBALL:
- return ICON_OUTLINER_OB_META;
- case OB_LATTICE:
- return ICON_OUTLINER_OB_LATTICE;
- case OB_SPEAKER:
- return ICON_OUTLINER_OB_SPEAKER;
- case OB_LIGHTPROBE:
- return ICON_OUTLINER_OB_LIGHTPROBE;
- case OB_ARMATURE:
- return ICON_OUTLINER_OB_ARMATURE;
- case OB_FONT:
- return ICON_OUTLINER_OB_FONT;
- case OB_SURF:
- return ICON_OUTLINER_OB_SURFACE;
- case OB_EMPTY:
- return ICON_OUTLINER_OB_EMPTY;
- case OB_GPENCIL:
- return ICON_OUTLINER_OB_GREASEPENCIL;
- default:
- return ICON_OBJECT_DATA;
- }
+ Base *base = (Base *)ale->data;
+ Object *ob = base->object;
+
+ /* icon depends on object-type */
+ switch (ob->type) {
+ case OB_LAMP:
+ return ICON_OUTLINER_OB_LIGHT;
+ case OB_MESH:
+ return ICON_OUTLINER_OB_MESH;
+ case OB_CAMERA:
+ return ICON_OUTLINER_OB_CAMERA;
+ case OB_CURVE:
+ return ICON_OUTLINER_OB_CURVE;
+ case OB_MBALL:
+ return ICON_OUTLINER_OB_META;
+ case OB_LATTICE:
+ return ICON_OUTLINER_OB_LATTICE;
+ case OB_SPEAKER:
+ return ICON_OUTLINER_OB_SPEAKER;
+ case OB_LIGHTPROBE:
+ return ICON_OUTLINER_OB_LIGHTPROBE;
+ case OB_ARMATURE:
+ return ICON_OUTLINER_OB_ARMATURE;
+ case OB_FONT:
+ return ICON_OUTLINER_OB_FONT;
+ case OB_SURF:
+ return ICON_OUTLINER_OB_SURFACE;
+ case OB_EMPTY:
+ return ICON_OUTLINER_OB_EMPTY;
+ case OB_GPENCIL:
+ return ICON_OUTLINER_OB_GREASEPENCIL;
+ default:
+ return ICON_OBJECT_DATA;
+ }
}
/* name for object */
static void acf_object_name(bAnimListElem *ale, char *name)
{
- Base *base = (Base *)ale->data;
- Object *ob = base->object;
+ Base *base = (Base *)ale->data;
+ Object *ob = base->object;
- /* just copy the name... */
- if (ob && name)
- BLI_strncpy(name, ob->id.name + 2, ANIM_CHAN_NAME_SIZE);
+ /* just copy the name... */
+ if (ob && name)
+ BLI_strncpy(name, ob->id.name + 2, ANIM_CHAN_NAME_SIZE);
}
/* name property for object */
static bool acf_object_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
{
- RNA_id_pointer_create(ale->id, ptr);
- *prop = RNA_struct_name_property(ptr->type);
+ RNA_id_pointer_create(ale->id, ptr);
+ *prop = RNA_struct_name_property(ptr->type);
- return (*prop != NULL);
+ return (*prop != NULL);
}
/* check if some setting exists for this channel */
-static bool acf_object_setting_valid(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
+static bool acf_object_setting_valid(bAnimContext *ac,
+ bAnimListElem *ale,
+ eAnimChannel_Settings setting)
{
- Base *base = (Base *)ale->data;
- Object *ob = base->object;
+ Base *base = (Base *)ale->data;
+ Object *ob = base->object;
- switch (setting) {
- /* muted only in NLA */
- case ACHANNEL_SETTING_MUTE:
- return ((ac) && (ac->spacetype == SPACE_NLA));
+ switch (setting) {
+ /* muted only in NLA */
+ case ACHANNEL_SETTING_MUTE:
+ return ((ac) && (ac->spacetype == SPACE_NLA));
- /* visible only in Graph Editor */
- case ACHANNEL_SETTING_VISIBLE:
- return ((ac) && (ac->spacetype == SPACE_GRAPH) && (ob->adt));
+ /* visible only in Graph Editor */
+ case ACHANNEL_SETTING_VISIBLE:
+ return ((ac) && (ac->spacetype == SPACE_GRAPH) && (ob->adt));
- /* only select and expand supported otherwise */
- case ACHANNEL_SETTING_SELECT:
- case ACHANNEL_SETTING_EXPAND:
- return true;
+ /* only select and expand supported otherwise */
+ case ACHANNEL_SETTING_SELECT:
+ case ACHANNEL_SETTING_EXPAND:
+ return true;
- case ACHANNEL_SETTING_ALWAYS_VISIBLE:
- return ((ac) && (ac->spacetype == SPACE_GRAPH) && (ob->adt));
+ case ACHANNEL_SETTING_ALWAYS_VISIBLE:
+ return ((ac) && (ac->spacetype == SPACE_GRAPH) && (ob->adt));
- default:
- return false;
- }
+ default:
+ return false;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_object_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_object_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- return BASE_SELECTED;
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return BASE_SELECTED;
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- *neg = 1;
- return OB_ADS_COLLAPSED;
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ *neg = 1;
+ return OB_ADS_COLLAPSED;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_ALWAYS_VISIBLE:
- return ADT_CURVES_ALWAYS_VISIBLE;
+ case ACHANNEL_SETTING_ALWAYS_VISIBLE:
+ return ADT_CURVES_ALWAYS_VISIBLE;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
static void *acf_object_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- Base *base = (Base *)ale->data;
- Object *ob = base->object;
+ Base *base = (Base *)ale->data;
+ Object *ob = base->object;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- return GET_ACF_FLAG_PTR(base->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return GET_ACF_FLAG_PTR(base->flag, type);
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(ob->nlaflag, type); // xxx
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(ob->nlaflag, type); // xxx
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- case ACHANNEL_SETTING_ALWAYS_VISIBLE:
- if (ob->adt)
- return GET_ACF_FLAG_PTR(ob->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ case ACHANNEL_SETTING_ALWAYS_VISIBLE:
+ if (ob->adt)
+ return GET_ACF_FLAG_PTR(ob->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* object type define */
-static bAnimChannelType ACF_OBJECT =
-{
- "Object", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_root_color, /* backdrop color */
- acf_generic_root_backdrop, /* backdrop */
- acf_generic_indention_0, /* indent level */
- NULL, /* offset */
-
- acf_object_name, /* name */
- acf_object_name_prop, /* name prop */
- acf_object_icon, /* icon */
-
- acf_object_setting_valid, /* has setting */
- acf_object_setting_flag, /* flag for setting */
- acf_object_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_OBJECT = {
+ "Object", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_root_color, /* backdrop color */
+ acf_generic_root_backdrop, /* backdrop */
+ acf_generic_indention_0, /* indent level */
+ NULL, /* offset */
+
+ acf_object_name, /* name */
+ acf_object_name_prop, /* name prop */
+ acf_object_icon, /* icon */
+
+ acf_object_setting_valid, /* has setting */
+ acf_object_setting_flag, /* flag for setting */
+ acf_object_setting_ptr, /* pointer for setting */
};
/* Group ------------------------------------------- */
@@ -808,158 +834,161 @@ static bAnimChannelType ACF_OBJECT =
/* get backdrop color for group widget */
static void acf_group_color(bAnimContext *ac, bAnimListElem *ale, float r_color[3])
{
- bActionGroup *agrp = (bActionGroup *)ale->data;
- bool showGroupColors = acf_show_channel_colors(ac);
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+ bool showGroupColors = acf_show_channel_colors(ac);
- if (showGroupColors && agrp->customCol) {
- unsigned char cp[3];
+ if (showGroupColors && agrp->customCol) {
+ unsigned char cp[3];
- /* highlight only for active */
- if (ale->flag & AGRP_ACTIVE)
- copy_v3_v3_char((char *)cp, agrp->cs.select);
- else
- copy_v3_v3_char((char *)cp, agrp->cs.solid);
+ /* highlight only for active */
+ if (ale->flag & AGRP_ACTIVE)
+ copy_v3_v3_char((char *)cp, agrp->cs.select);
+ else
+ copy_v3_v3_char((char *)cp, agrp->cs.solid);
- /* copy the colors over, transforming from bytes to floats */
- rgb_uchar_to_float(r_color, cp);
- }
- else {
- /* highlight only for active */
- if (ale->flag & AGRP_ACTIVE)
- UI_GetThemeColor3fv(TH_GROUP_ACTIVE, r_color);
- else
- UI_GetThemeColor3fv(TH_GROUP, r_color);
- }
+ /* copy the colors over, transforming from bytes to floats */
+ rgb_uchar_to_float(r_color, cp);
+ }
+ else {
+ /* highlight only for active */
+ if (ale->flag & AGRP_ACTIVE)
+ UI_GetThemeColor3fv(TH_GROUP_ACTIVE, r_color);
+ else
+ UI_GetThemeColor3fv(TH_GROUP, r_color);
+ }
}
/* backdrop for group widget */
static void acf_group_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- View2D *v2d = &ac->ar->v2d;
- short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
- short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
- float color[3];
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ View2D *v2d = &ac->ar->v2d;
+ short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
+ short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+ float color[3];
- /* set backdrop drawing color */
- acf->get_backdrop_color(ac, ale, color);
+ /* set backdrop drawing color */
+ acf->get_backdrop_color(ac, ale, color);
- /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
- UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
- UI_draw_roundbox_3fvAlpha(true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
+ /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
+ UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
+ UI_draw_roundbox_3fvAlpha(
+ true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 8, color, 1.0f);
}
/* name for group entries */
static void acf_group_name(bAnimListElem *ale, char *name)
{
- bActionGroup *agrp = (bActionGroup *)ale->data;
+ bActionGroup *agrp = (bActionGroup *)ale->data;
- /* just copy the name... */
- if (agrp && name)
- BLI_strncpy(name, agrp->name, ANIM_CHAN_NAME_SIZE);
+ /* just copy the name... */
+ if (agrp && name)
+ BLI_strncpy(name, agrp->name, ANIM_CHAN_NAME_SIZE);
}
/* name property for group entries */
static bool acf_group_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
{
- RNA_pointer_create(ale->id, &RNA_ActionGroup, ale->data, ptr);
- *prop = RNA_struct_name_property(ptr->type);
+ RNA_pointer_create(ale->id, &RNA_ActionGroup, ale->data, ptr);
+ *prop = RNA_struct_name_property(ptr->type);
- return (*prop != NULL);
+ return (*prop != NULL);
}
/* check if some setting exists for this channel */
-static bool acf_group_setting_valid(bAnimContext *ac, bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
+static bool acf_group_setting_valid(bAnimContext *ac,
+ bAnimListElem *UNUSED(ale),
+ eAnimChannel_Settings setting)
{
- /* for now, all settings are supported, though some are only conditionally */
- switch (setting) {
- /* unsupported */
- case ACHANNEL_SETTING_SOLO: /* Only available in NLA Editor for tracks */
- return false;
+ /* for now, all settings are supported, though some are only conditionally */
+ switch (setting) {
+ /* unsupported */
+ case ACHANNEL_SETTING_SOLO: /* Only available in NLA Editor for tracks */
+ return false;
- /* conditionally supported */
- case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */
- return (ac->spacetype == SPACE_GRAPH);
+ /* conditionally supported */
+ case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */
+ return (ac->spacetype == SPACE_GRAPH);
- case ACHANNEL_SETTING_ALWAYS_VISIBLE:
- return (ac->spacetype == SPACE_GRAPH);
+ case ACHANNEL_SETTING_ALWAYS_VISIBLE:
+ return (ac->spacetype == SPACE_GRAPH);
- default: /* always supported */
- return true;
- }
+ default: /* always supported */
+ return true;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
static int acf_group_setting_flag(bAnimContext *ac, eAnimChannel_Settings setting, bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- return AGRP_SELECTED;
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return AGRP_SELECTED;
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- {
- /* NOTE: Graph Editor uses a different flag to everywhere else for this,
- * allowing different collapsing of groups there, since sharing the flag
- * proved to be a hazard for workflows...
- */
- return (ac->spacetype == SPACE_GRAPH) ?
- AGRP_EXPANDED_G : /* Graph Editor case */
- AGRP_EXPANDED; /* DopeSheet and elsewhere */
- }
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ {
+ /* NOTE: Graph Editor uses a different flag to everywhere else for this,
+ * allowing different collapsing of groups there, since sharing the flag
+ * proved to be a hazard for workflows...
+ */
+ return (ac->spacetype == SPACE_GRAPH) ? AGRP_EXPANDED_G : /* Graph Editor case */
+ AGRP_EXPANDED; /* DopeSheet and elsewhere */
+ }
- case ACHANNEL_SETTING_MUTE: /* muted */
- return AGRP_MUTED;
+ case ACHANNEL_SETTING_MUTE: /* muted */
+ return AGRP_MUTED;
- case ACHANNEL_SETTING_MOD_OFF: /* muted */
- *neg = 1;
- return AGRP_MODIFIERS_OFF;
+ case ACHANNEL_SETTING_MOD_OFF: /* muted */
+ *neg = 1;
+ return AGRP_MODIFIERS_OFF;
- case ACHANNEL_SETTING_PROTECT: /* protected */
- return AGRP_PROTECTED;
+ case ACHANNEL_SETTING_PROTECT: /* protected */
+ return AGRP_PROTECTED;
- case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */
- *neg = 1;
- return AGRP_NOTVISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */
+ *neg = 1;
+ return AGRP_NOTVISIBLE;
- case ACHANNEL_SETTING_ALWAYS_VISIBLE:
- return ADT_CURVES_ALWAYS_VISIBLE;
+ case ACHANNEL_SETTING_ALWAYS_VISIBLE:
+ return ADT_CURVES_ALWAYS_VISIBLE;
- default:
- /* this shouldn't happen */
- return 0;
- }
+ default:
+ /* this shouldn't happen */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_group_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
+static void *acf_group_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings UNUSED(setting),
+ short *type)
{
- bActionGroup *agrp = (bActionGroup *)ale->data;
+ bActionGroup *agrp = (bActionGroup *)ale->data;
- /* all flags are just in agrp->flag for now... */
- return GET_ACF_FLAG_PTR(agrp->flag, type);
+ /* all flags are just in agrp->flag for now... */
+ return GET_ACF_FLAG_PTR(agrp->flag, type);
}
/* group type define */
-static bAnimChannelType ACF_GROUP =
-{
- "Group", /* type name */
- ACHANNEL_ROLE_CHANNEL, /* role */
-
- acf_group_color, /* backdrop color */
- acf_group_backdrop, /* backdrop */
- acf_generic_indention_0, /* indent level */
- acf_generic_group_offset, /* offset */
-
- acf_group_name, /* name */
- acf_group_name_prop, /* name prop */
- NULL, /* icon */
-
- acf_group_setting_valid, /* has setting */
- acf_group_setting_flag, /* flag for setting */
- acf_group_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_GROUP = {
+ "Group", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
+
+ acf_group_color, /* backdrop color */
+ acf_group_backdrop, /* backdrop */
+ acf_generic_indention_0, /* indent level */
+ acf_generic_group_offset, /* offset */
+
+ acf_group_name, /* name */
+ acf_group_name_prop, /* name prop */
+ NULL, /* icon */
+
+ acf_group_setting_valid, /* has setting */
+ acf_group_setting_flag, /* flag for setting */
+ acf_group_setting_ptr, /* pointer for setting */
};
/* F-Curve ------------------------------------------- */
@@ -967,258 +996,272 @@ static bAnimChannelType ACF_GROUP =
/* name for fcurve entries */
static void acf_fcurve_name(bAnimListElem *ale, char *name)
{
- getname_anim_fcurve(name, ale->id, ale->data);
+ getname_anim_fcurve(name, ale->id, ale->data);
}
/* "name" property for fcurve entries */
static bool acf_fcurve_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
{
- FCurve *fcu = (FCurve *)ale->data;
+ FCurve *fcu = (FCurve *)ale->data;
- /* Ctrl-Click Usability Convenience Hack:
- * For disabled F-Curves, allow access to the RNA Path
- * as our "name" so that user can perform quick fixes
- */
- if (fcu->flag & FCURVE_DISABLED) {
- RNA_pointer_create(ale->id, &RNA_FCurve, ale->data, ptr);
- *prop = RNA_struct_find_property(ptr, "data_path");
- }
- else {
- /* for "normal" F-Curves - no editable name, but *prop may not be set properly yet... */
- *prop = NULL;
- }
+ /* Ctrl-Click Usability Convenience Hack:
+ * For disabled F-Curves, allow access to the RNA Path
+ * as our "name" so that user can perform quick fixes
+ */
+ if (fcu->flag & FCURVE_DISABLED) {
+ RNA_pointer_create(ale->id, &RNA_FCurve, ale->data, ptr);
+ *prop = RNA_struct_find_property(ptr, "data_path");
+ }
+ else {
+ /* for "normal" F-Curves - no editable name, but *prop may not be set properly yet... */
+ *prop = NULL;
+ }
- return (*prop != NULL);
+ return (*prop != NULL);
}
/* check if some setting exists for this channel */
-static bool acf_fcurve_setting_valid(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
+static bool acf_fcurve_setting_valid(bAnimContext *ac,
+ bAnimListElem *ale,
+ eAnimChannel_Settings setting)
{
- FCurve *fcu = (FCurve *)ale->data;
+ FCurve *fcu = (FCurve *)ale->data;
- switch (setting) {
- /* unsupported */
- case ACHANNEL_SETTING_SOLO: /* Solo Flag is only for NLA */
- case ACHANNEL_SETTING_EXPAND: /* F-Curves are not containers */
- case ACHANNEL_SETTING_PINNED: /* This is only for NLA Actions */
- return false;
+ switch (setting) {
+ /* unsupported */
+ case ACHANNEL_SETTING_SOLO: /* Solo Flag is only for NLA */
+ case ACHANNEL_SETTING_EXPAND: /* F-Curves are not containers */
+ case ACHANNEL_SETTING_PINNED: /* This is only for NLA Actions */
+ return false;
- /* conditionally available */
- case ACHANNEL_SETTING_PROTECT: /* Protection is only valid when there's keyframes */
- if (fcu->bezt)
- return true;
- else
- return false; // NOTE: in this special case, we need to draw ICON_ZOOMOUT
+ /* conditionally available */
+ case ACHANNEL_SETTING_PROTECT: /* Protection is only valid when there's keyframes */
+ if (fcu->bezt)
+ return true;
+ else
+ return false; // NOTE: in this special case, we need to draw ICON_ZOOMOUT
- case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */
- return (ac->spacetype == SPACE_GRAPH);
+ case ACHANNEL_SETTING_VISIBLE: /* Only available in Graph Editor */
+ return (ac->spacetype == SPACE_GRAPH);
- case ACHANNEL_SETTING_ALWAYS_VISIBLE:
- return false;
+ case ACHANNEL_SETTING_ALWAYS_VISIBLE:
+ return false;
- /* always available */
- default:
- return true;
- }
+ /* always available */
+ default:
+ return true;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- return FCURVE_SELECTED;
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return FCURVE_SELECTED;
- case ACHANNEL_SETTING_MUTE: /* muted */
- return FCURVE_MUTED;
+ case ACHANNEL_SETTING_MUTE: /* muted */
+ return FCURVE_MUTED;
- case ACHANNEL_SETTING_PROTECT: /* protected */
- return FCURVE_PROTECTED;
+ case ACHANNEL_SETTING_PROTECT: /* protected */
+ return FCURVE_PROTECTED;
- case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */
- return FCURVE_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */
+ return FCURVE_VISIBLE;
- case ACHANNEL_SETTING_MOD_OFF:
- *neg = 1;
- return FCURVE_MOD_OFF;
+ case ACHANNEL_SETTING_MOD_OFF:
+ *neg = 1;
+ return FCURVE_MOD_OFF;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_fcurve_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
+static void *acf_fcurve_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings UNUSED(setting),
+ short *type)
{
- FCurve *fcu = (FCurve *)ale->data;
+ FCurve *fcu = (FCurve *)ale->data;
- /* all flags are just in agrp->flag for now... */
- return GET_ACF_FLAG_PTR(fcu->flag, type);
+ /* all flags are just in agrp->flag for now... */
+ return GET_ACF_FLAG_PTR(fcu->flag, type);
}
/* fcurve type define */
-static bAnimChannelType ACF_FCURVE =
-{
- "F-Curve", /* type name */
- ACHANNEL_ROLE_CHANNEL, /* role */
-
- acf_generic_channel_color, /* backdrop color */
- acf_generic_channel_backdrop, /* backdrop */
- acf_generic_indention_flexible, /* indent level */ // xxx rename this to f-curves only?
- acf_generic_group_offset, /* offset */
-
- acf_fcurve_name, /* name */
- acf_fcurve_name_prop, /* name prop */
- NULL, /* icon */
-
- acf_fcurve_setting_valid, /* has setting */
- acf_fcurve_setting_flag, /* flag for setting */
- acf_fcurve_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_FCURVE = {
+ "F-Curve", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
+
+ acf_generic_channel_color, /* backdrop color */
+ acf_generic_channel_backdrop, /* backdrop */
+ acf_generic_indention_flexible,
+ /* indent level */ // xxx rename this to f-curves only?
+ acf_generic_group_offset, /* offset */
+
+ acf_fcurve_name, /* name */
+ acf_fcurve_name_prop, /* name prop */
+ NULL, /* icon */
+
+ acf_fcurve_setting_valid, /* has setting */
+ acf_fcurve_setting_flag, /* flag for setting */
+ acf_fcurve_setting_ptr, /* pointer for setting */
};
/* NLA Control FCurves Expander ----------------------- */
/* get backdrop color for nla controls widget */
-static void acf_nla_controls_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3])
+static void acf_nla_controls_color(bAnimContext *UNUSED(ac),
+ bAnimListElem *UNUSED(ale),
+ float r_color[3])
{
- // TODO: give this its own theme setting?
- UI_GetThemeColorShade3fv(TH_GROUP, 55, r_color);
+ // TODO: give this its own theme setting?
+ UI_GetThemeColorShade3fv(TH_GROUP, 55, r_color);
}
/* backdrop for nla controls expander widget */
-static void acf_nla_controls_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
+static void acf_nla_controls_backdrop(bAnimContext *ac,
+ bAnimListElem *ale,
+ float yminc,
+ float ymaxc)
{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- View2D *v2d = &ac->ar->v2d;
- short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
- short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
- float color[3];
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ View2D *v2d = &ac->ar->v2d;
+ short expanded = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_EXPAND) != 0;
+ short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+ float color[3];
- /* set backdrop drawing color */
- acf->get_backdrop_color(ac, ale, color);
+ /* set backdrop drawing color */
+ acf->get_backdrop_color(ac, ale, color);
- /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
- UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
- UI_draw_roundbox_3fvAlpha(true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 5, color, 1.0f);
+ /* rounded corners on LHS only - top only when expanded, but bottom too when collapsed */
+ UI_draw_roundbox_corner_set(expanded ? UI_CNR_TOP_LEFT : (UI_CNR_TOP_LEFT | UI_CNR_BOTTOM_LEFT));
+ UI_draw_roundbox_3fvAlpha(
+ true, offset, yminc, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc, 5, color, 1.0f);
}
/* name for nla controls expander entries */
static void acf_nla_controls_name(bAnimListElem *UNUSED(ale), char *name)
{
- BLI_strncpy(name, IFACE_("NLA Strip Controls"), ANIM_CHAN_NAME_SIZE);
+ BLI_strncpy(name, IFACE_("NLA Strip Controls"), ANIM_CHAN_NAME_SIZE);
}
/* check if some setting exists for this channel */
-static bool acf_nla_controls_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
+static bool acf_nla_controls_setting_valid(bAnimContext *UNUSED(ac),
+ bAnimListElem *UNUSED(ale),
+ eAnimChannel_Settings setting)
{
- /* for now, all settings are supported, though some are only conditionally */
- switch (setting) {
- /* supported */
- case ACHANNEL_SETTING_EXPAND:
- return true;
+ /* for now, all settings are supported, though some are only conditionally */
+ switch (setting) {
+ /* supported */
+ case ACHANNEL_SETTING_EXPAND:
+ return true;
- // TODO: selected?
+ // TODO: selected?
- default: /* unsupported */
- return false;
- }
+ default: /* unsupported */
+ return false;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_nla_controls_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_nla_controls_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- *neg = true;
- return ADT_NLA_SKEYS_COLLAPSED;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ *neg = true;
+ return ADT_NLA_SKEYS_COLLAPSED;
- default:
- /* this shouldn't happen */
- return 0;
- }
+ default:
+ /* this shouldn't happen */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_nla_controls_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
+static void *acf_nla_controls_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings UNUSED(setting),
+ short *type)
{
- AnimData *adt = (AnimData *)ale->data;
+ AnimData *adt = (AnimData *)ale->data;
- /* all flags are just in adt->flag for now... */
- return GET_ACF_FLAG_PTR(adt->flag, type);
+ /* all flags are just in adt->flag for now... */
+ return GET_ACF_FLAG_PTR(adt->flag, type);
}
static int acf_nla_controls_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_NLA;
+ return ICON_NLA;
}
/* NLA Control FCurves Expander type define */
-static bAnimChannelType ACF_NLACONTROLS =
-{
- "NLA Controls Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_nla_controls_color, /* backdrop color */
- acf_nla_controls_backdrop, /* backdrop */
- acf_generic_indention_0, /* indent level */
- acf_generic_group_offset, /* offset */
-
- acf_nla_controls_name, /* name */
- NULL, /* name prop */
- acf_nla_controls_icon, /* icon */
-
- acf_nla_controls_setting_valid, /* has setting */
- acf_nla_controls_setting_flag, /* flag for setting */
- acf_nla_controls_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_NLACONTROLS = {
+ "NLA Controls Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_nla_controls_color, /* backdrop color */
+ acf_nla_controls_backdrop, /* backdrop */
+ acf_generic_indention_0, /* indent level */
+ acf_generic_group_offset, /* offset */
+
+ acf_nla_controls_name, /* name */
+ NULL, /* name prop */
+ acf_nla_controls_icon, /* icon */
+
+ acf_nla_controls_setting_valid, /* has setting */
+ acf_nla_controls_setting_flag, /* flag for setting */
+ acf_nla_controls_setting_ptr, /* pointer for setting */
};
-
/* NLA Control F-Curve -------------------------------- */
/* name for nla control fcurve entries */
static void acf_nla_curve_name(bAnimListElem *ale, char *name)
{
- NlaStrip *strip = ale->owner;
- FCurve *fcu = ale->data;
- PropertyRNA *prop;
+ NlaStrip *strip = ale->owner;
+ FCurve *fcu = ale->data;
+ PropertyRNA *prop;
- /* try to get RNA property that this shortened path (relative to the strip) refers to */
- prop = RNA_struct_type_find_property(&RNA_NlaStrip, fcu->rna_path);
- if (prop) {
- /* "name" of this strip displays the UI identifier + the name of the NlaStrip */
- BLI_snprintf(name, 256, "%s (%s)", RNA_property_ui_name(prop), strip->name);
- }
- else {
- /* unknown property... */
- BLI_snprintf(name, 256, "%s[%d]", fcu->rna_path, fcu->array_index);
- }
+ /* try to get RNA property that this shortened path (relative to the strip) refers to */
+ prop = RNA_struct_type_find_property(&RNA_NlaStrip, fcu->rna_path);
+ if (prop) {
+ /* "name" of this strip displays the UI identifier + the name of the NlaStrip */
+ BLI_snprintf(name, 256, "%s (%s)", RNA_property_ui_name(prop), strip->name);
+ }
+ else {
+ /* unknown property... */
+ BLI_snprintf(name, 256, "%s[%d]", fcu->rna_path, fcu->array_index);
+ }
}
-
/* NLA Control F-Curve type define */
-static bAnimChannelType ACF_NLACURVE =
-{
- "NLA Control F-Curve", /* type name */
- ACHANNEL_ROLE_CHANNEL, /* role */
-
- acf_generic_channel_color, /* backdrop color */
- acf_generic_channel_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_group_offset, /* offset */
-
- acf_nla_curve_name, /* name */
- acf_fcurve_name_prop, /* name prop */
- NULL, /* icon */
-
- acf_fcurve_setting_valid, /* has setting */
- acf_fcurve_setting_flag, /* flag for setting */
- acf_fcurve_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_NLACURVE = {
+ "NLA Control F-Curve", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
+
+ acf_generic_channel_color, /* backdrop color */
+ acf_generic_channel_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_group_offset, /* offset */
+
+ acf_nla_curve_name, /* name */
+ acf_fcurve_name_prop, /* name prop */
+ NULL, /* icon */
+
+ acf_fcurve_setting_valid, /* has setting */
+ acf_fcurve_setting_flag, /* flag for setting */
+ acf_fcurve_setting_ptr, /* pointer for setting */
};
/* Object Action Expander ------------------------------------------- */
@@ -1226,84 +1269,89 @@ static bAnimChannelType ACF_NLACURVE =
// TODO: just get this from RNA?
static int acf_fillactd_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_ACTION;
+ return ICON_ACTION;
}
/* check if some setting exists for this channel */
-static bool acf_fillactd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
+static bool acf_fillactd_setting_valid(bAnimContext *UNUSED(ac),
+ bAnimListElem *UNUSED(ale),
+ eAnimChannel_Settings setting)
{
- switch (setting) {
- /* only select and expand supported */
- case ACHANNEL_SETTING_SELECT:
- case ACHANNEL_SETTING_EXPAND:
- return true;
+ switch (setting) {
+ /* only select and expand supported */
+ case ACHANNEL_SETTING_SELECT:
+ case ACHANNEL_SETTING_EXPAND:
+ return true;
- default:
- return false;
- }
+ default:
+ return false;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_fillactd_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- *neg = true;
- return ACT_COLLAPSED;
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ *neg = true;
+ return ACT_COLLAPSED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_fillactd_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
+static void *acf_fillactd_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings setting,
+ short *type)
{
- bAction *act = (bAction *)ale->data;
- AnimData *adt = ale->adt;
+ bAction *act = (bAction *)ale->data;
+ AnimData *adt = ale->adt;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- if (adt) {
- return GET_ACF_FLAG_PTR(adt->flag, type);
- }
- return NULL;
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ if (adt) {
+ return GET_ACF_FLAG_PTR(adt->flag, type);
+ }
+ return NULL;
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(act->flag, type);
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(act->flag, type);
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* object action expander type define */
-static bAnimChannelType ACF_FILLACTD =
-{
- "Ob-Action Filler", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idfill_name_prop, /* name prop */
- acf_fillactd_icon, /* icon */
-
- acf_fillactd_setting_valid, /* has setting */
- acf_fillactd_setting_flag, /* flag for setting */
- acf_fillactd_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_FILLACTD = {
+ "Ob-Action Filler", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idfill_name_prop, /* name prop */
+ acf_fillactd_icon, /* icon */
+
+ acf_fillactd_setting_valid, /* has setting */
+ acf_fillactd_setting_flag, /* flag for setting */
+ acf_fillactd_setting_ptr, /* pointer for setting */
};
/* Drivers Expander ------------------------------------------- */
@@ -1311,157 +1359,162 @@ static bAnimChannelType ACF_FILLACTD =
// TODO: just get this from RNA?
static int acf_filldrivers_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_DRIVER;
+ return ICON_DRIVER;
}
static void acf_filldrivers_name(bAnimListElem *UNUSED(ale), char *name)
{
- BLI_strncpy(name, IFACE_("Drivers"), ANIM_CHAN_NAME_SIZE);
+ BLI_strncpy(name, IFACE_("Drivers"), ANIM_CHAN_NAME_SIZE);
}
/* check if some setting exists for this channel */
// TODO: this could be made more generic
-static bool acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
+static bool acf_filldrivers_setting_valid(bAnimContext *UNUSED(ac),
+ bAnimListElem *UNUSED(ale),
+ eAnimChannel_Settings setting)
{
- switch (setting) {
- /* only expand supported */
- case ACHANNEL_SETTING_EXPAND:
- return true;
+ switch (setting) {
+ /* only expand supported */
+ case ACHANNEL_SETTING_EXPAND:
+ return true;
- default:
- return false;
- }
+ default:
+ return false;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_filldrivers_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- *neg = true;
- return ADT_DRIVERS_COLLAPSED;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ *neg = true;
+ return ADT_DRIVERS_COLLAPSED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_filldrivers_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
+static void *acf_filldrivers_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings setting,
+ short *type)
{
- AnimData *adt = (AnimData *)ale->data;
+ AnimData *adt = (AnimData *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(adt->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(adt->flag, type);
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* drivers expander type define */
-static bAnimChannelType ACF_FILLDRIVERS =
-{
- "Drivers Filler", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_filldrivers_name, /* name */
- NULL, /* name prop */
- acf_filldrivers_icon, /* icon */
-
- acf_filldrivers_setting_valid, /* has setting */
- acf_filldrivers_setting_flag, /* flag for setting */
- acf_filldrivers_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_FILLDRIVERS = {
+ "Drivers Filler", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_filldrivers_name, /* name */
+ NULL, /* name prop */
+ acf_filldrivers_icon, /* icon */
+
+ acf_filldrivers_setting_valid, /* has setting */
+ acf_filldrivers_setting_flag, /* flag for setting */
+ acf_filldrivers_setting_ptr, /* pointer for setting */
};
-
/* Material Expander ------------------------------------------- */
// TODO: just get this from RNA?
static int acf_dsmat_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_MATERIAL_DATA;
+ return ICON_MATERIAL_DATA;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dsmat_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return MA_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return MA_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
static void *acf_dsmat_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- Material *ma = (Material *)ale->data;
+ Material *ma = (Material *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(ma->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(ma->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (ma->adt)
- return GET_ACF_FLAG_PTR(ma->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (ma->adt)
+ return GET_ACF_FLAG_PTR(ma->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* material expander type define */
-static bAnimChannelType ACF_DSMAT =
-{
- "Material Data Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_dsmat_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dsmat_setting_flag, /* flag for setting */
- acf_dsmat_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSMAT = {
+ "Material Data Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dsmat_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dsmat_setting_flag, /* flag for setting */
+ acf_dsmat_setting_ptr, /* pointer for setting */
};
/* Light Expander ------------------------------------------- */
@@ -1469,76 +1522,79 @@ static bAnimChannelType ACF_DSMAT =
// TODO: just get this from RNA?
static int acf_dslight_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_LIGHT_DATA;
+ return ICON_LIGHT_DATA;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dslight_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dslight_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return LA_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return LA_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_dslight_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
+static void *acf_dslight_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings setting,
+ short *type)
{
- Light *la = (Light *)ale->data;
+ Light *la = (Light *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(la->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(la->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (la->adt)
- return GET_ACF_FLAG_PTR(la->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (la->adt)
+ return GET_ACF_FLAG_PTR(la->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* light expander type define */
-static bAnimChannelType ACF_DSLIGHT =
-{
- "Light Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_dslight_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dslight_setting_flag, /* flag for setting */
- acf_dslight_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSLIGHT = {
+ "Light Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dslight_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dslight_setting_flag, /* flag for setting */
+ acf_dslight_setting_ptr, /* pointer for setting */
};
/* Texture Expander ------------------------------------------- */
@@ -1546,83 +1602,84 @@ static bAnimChannelType ACF_DSLIGHT =
// TODO: just get this from RNA?
static int acf_dstex_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_TEXTURE_DATA;
+ return ICON_TEXTURE_DATA;
}
/* offset for texture expanders */
// FIXME: soon to be obsolete?
static short acf_dstex_offset(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale))
{
- return 14; // XXX: simply include this in indention instead?
+ return 14; // XXX: simply include this in indention instead?
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dstex_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return TEX_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return TEX_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
static void *acf_dstex_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- Tex *tex = (Tex *)ale->data;
+ Tex *tex = (Tex *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(tex->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(tex->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (tex->adt)
- return GET_ACF_FLAG_PTR(tex->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (tex->adt)
+ return GET_ACF_FLAG_PTR(tex->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* texture expander type define */
-static bAnimChannelType ACF_DSTEX =
-{
- "Texture Data Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_dstex_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idfill_name_prop, /* name prop */
- acf_dstex_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dstex_setting_flag, /* flag for setting */
- acf_dstex_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSTEX = {
+ "Texture Data Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_dstex_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idfill_name_prop, /* name prop */
+ acf_dstex_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dstex_setting_flag, /* flag for setting */
+ acf_dstex_setting_ptr, /* pointer for setting */
};
/* Camera Expander ------------------------------------------- */
@@ -1630,81 +1687,82 @@ static bAnimChannelType ACF_DSTEX =
// TODO: just get this from RNA?
static int acf_dscachefile_icon(bAnimListElem *ale)
{
- UNUSED_VARS(ale);
- return ICON_FILE;
+ UNUSED_VARS(ale);
+ return ICON_FILE;
}
/* get the appropriate flag(s) for the setting when it is valid */
static int acf_dscachefile_setting_flag(bAnimContext *ac, eAnimChannel_Settings setting, bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return CACHEFILE_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return CACHEFILE_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
- UNUSED_VARS(ac);
+ UNUSED_VARS(ac);
}
/* get pointer to the setting */
-static void *acf_dscachefile_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
+static void *acf_dscachefile_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings setting,
+ short *type)
{
- CacheFile *cache_file = (CacheFile *)ale->data;
+ CacheFile *cache_file = (CacheFile *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(cache_file->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(cache_file->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (cache_file->adt) {
- return GET_ACF_FLAG_PTR(cache_file->adt->flag, type);
- }
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (cache_file->adt) {
+ return GET_ACF_FLAG_PTR(cache_file->adt->flag, type);
+ }
- return NULL;
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* CacheFile expander type define. */
-static bAnimChannelType ACF_DSCACHEFILE =
-{
- "Cache File Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idfill_name_prop, /* name prop */
- acf_dscachefile_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dscachefile_setting_flag, /* flag for setting */
- acf_dscachefile_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSCACHEFILE = {
+ "Cache File Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idfill_name_prop, /* name prop */
+ acf_dscachefile_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dscachefile_setting_flag, /* flag for setting */
+ acf_dscachefile_setting_ptr, /* pointer for setting */
};
/* Camera Expander ------------------------------------------- */
@@ -1712,80 +1770,81 @@ static bAnimChannelType ACF_DSCACHEFILE =
// TODO: just get this from RNA?
static int acf_dscam_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_CAMERA_DATA;
+ return ICON_CAMERA_DATA;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dscam_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return CAM_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return CAM_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- case ACHANNEL_SETTING_ALWAYS_VISIBLE:
- return ADT_CURVES_ALWAYS_VISIBLE;
+ case ACHANNEL_SETTING_ALWAYS_VISIBLE:
+ return ADT_CURVES_ALWAYS_VISIBLE;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
static void *acf_dscam_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- Camera *ca = (Camera *)ale->data;
+ Camera *ca = (Camera *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(ca->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(ca->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- case ACHANNEL_SETTING_ALWAYS_VISIBLE:
- if (ca->adt)
- return GET_ACF_FLAG_PTR(ca->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ case ACHANNEL_SETTING_ALWAYS_VISIBLE:
+ if (ca->adt)
+ return GET_ACF_FLAG_PTR(ca->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* camera expander type define */
-static bAnimChannelType ACF_DSCAM =
-{
- "Camera Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idfill_name_prop, /* name prop */
- acf_dscam_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dscam_setting_flag, /* flag for setting */
- acf_dscam_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSCAM = {
+ "Camera Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idfill_name_prop, /* name prop */
+ acf_dscam_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dscam_setting_flag, /* flag for setting */
+ acf_dscam_setting_ptr, /* pointer for setting */
};
/* Curve Expander ------------------------------------------- */
@@ -1793,86 +1852,87 @@ static bAnimChannelType ACF_DSCAM =
// TODO: just get this from RNA?
static int acf_dscur_icon(bAnimListElem *ale)
{
- Curve *cu = (Curve *)ale->data;
- short obtype = BKE_curve_type_get(cu);
+ Curve *cu = (Curve *)ale->data;
+ short obtype = BKE_curve_type_get(cu);
- switch (obtype) {
- case OB_FONT:
- return ICON_FONT_DATA;
- case OB_SURF:
- return ICON_SURFACE_DATA;
- default:
- return ICON_CURVE_DATA;
- }
+ switch (obtype) {
+ case OB_FONT:
+ return ICON_FONT_DATA;
+ case OB_SURF:
+ return ICON_SURFACE_DATA;
+ default:
+ return ICON_CURVE_DATA;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dscur_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return CU_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return CU_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
static void *acf_dscur_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- Curve *cu = (Curve *)ale->data;
+ Curve *cu = (Curve *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(cu->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(cu->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (cu->adt)
- return GET_ACF_FLAG_PTR(cu->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (cu->adt)
+ return GET_ACF_FLAG_PTR(cu->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* curve expander type define */
-static bAnimChannelType ACF_DSCUR =
-{
- "Curve Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_dscur_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dscur_setting_flag, /* flag for setting */
- acf_dscur_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSCUR = {
+ "Curve Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dscur_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dscur_setting_flag, /* flag for setting */
+ acf_dscur_setting_ptr, /* pointer for setting */
};
/* Shape Key Expander ------------------------------------------- */
@@ -1880,76 +1940,77 @@ static bAnimChannelType ACF_DSCUR =
// TODO: just get this from RNA?
static int acf_dsskey_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_SHAPEKEY_DATA;
+ return ICON_SHAPEKEY_DATA;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dsskey_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return KEY_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return KEY_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
static void *acf_dsskey_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- Key *key = (Key *)ale->data;
+ Key *key = (Key *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(key->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(key->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (key->adt)
- return GET_ACF_FLAG_PTR(key->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (key->adt)
+ return GET_ACF_FLAG_PTR(key->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* shapekey expander type define */
-static bAnimChannelType ACF_DSSKEY =
-{
- "Shape Key Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_dsskey_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dsskey_setting_flag, /* flag for setting */
- acf_dsskey_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSSKEY = {
+ "Shape Key Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dsskey_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dsskey_setting_flag, /* flag for setting */
+ acf_dsskey_setting_ptr, /* pointer for setting */
};
/* World Expander ------------------------------------------- */
@@ -1957,76 +2018,77 @@ static bAnimChannelType ACF_DSSKEY =
// TODO: just get this from RNA?
static int acf_dswor_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_WORLD_DATA;
+ return ICON_WORLD_DATA;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dswor_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return WO_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return WO_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
static void *acf_dswor_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- World *wo = (World *)ale->data;
+ World *wo = (World *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(wo->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(wo->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (wo->adt)
- return GET_ACF_FLAG_PTR(wo->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (wo->adt)
+ return GET_ACF_FLAG_PTR(wo->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* world expander type define */
-static bAnimChannelType ACF_DSWOR =
-{
- "World Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idfill_name_prop, /* name prop */
- acf_dswor_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dswor_setting_flag, /* flag for setting */
- acf_dswor_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSWOR = {
+ "World Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idfill_name_prop, /* name prop */
+ acf_dswor_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dswor_setting_flag, /* flag for setting */
+ acf_dswor_setting_ptr, /* pointer for setting */
};
/* Particle Expander ------------------------------------------- */
@@ -2034,76 +2096,77 @@ static bAnimChannelType ACF_DSWOR =
// TODO: just get this from RNA?
static int acf_dspart_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_PARTICLE_DATA;
+ return ICON_PARTICLE_DATA;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dspart_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return PART_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return PART_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
static void *acf_dspart_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- ParticleSettings *part = (ParticleSettings *)ale->data;
+ ParticleSettings *part = (ParticleSettings *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(part->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(part->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (part->adt)
- return GET_ACF_FLAG_PTR(part->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (part->adt)
+ return GET_ACF_FLAG_PTR(part->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* particle expander type define */
-static bAnimChannelType ACF_DSPART =
-{
- "Particle Data Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_dspart_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dspart_setting_flag, /* flag for setting */
- acf_dspart_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSPART = {
+ "Particle Data Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dspart_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dspart_setting_flag, /* flag for setting */
+ acf_dspart_setting_ptr, /* pointer for setting */
};
/* MetaBall Expander ------------------------------------------- */
@@ -2111,76 +2174,79 @@ static bAnimChannelType ACF_DSPART =
// TODO: just get this from RNA?
static int acf_dsmball_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_META_DATA;
+ return ICON_META_DATA;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dsmball_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return MB_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return MB_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_dsmball_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
+static void *acf_dsmball_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings setting,
+ short *type)
{
- MetaBall *mb = (MetaBall *)ale->data;
+ MetaBall *mb = (MetaBall *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(mb->flag2, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(mb->flag2, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (mb->adt)
- return GET_ACF_FLAG_PTR(mb->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (mb->adt)
+ return GET_ACF_FLAG_PTR(mb->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* metaball expander type define */
-static bAnimChannelType ACF_DSMBALL =
-{
- "Metaball Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_dsmball_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dsmball_setting_flag, /* flag for setting */
- acf_dsmball_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSMBALL = {
+ "Metaball Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dsmball_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dsmball_setting_flag, /* flag for setting */
+ acf_dsmball_setting_ptr, /* pointer for setting */
};
/* Armature Expander ------------------------------------------- */
@@ -2188,76 +2254,77 @@ static bAnimChannelType ACF_DSMBALL =
// TODO: just get this from RNA?
static int acf_dsarm_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_ARMATURE_DATA;
+ return ICON_ARMATURE_DATA;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dsarm_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return ARM_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return ARM_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
static void *acf_dsarm_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- bArmature *arm = (bArmature *)ale->data;
+ bArmature *arm = (bArmature *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(arm->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(arm->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (arm->adt)
- return GET_ACF_FLAG_PTR(arm->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (arm->adt)
+ return GET_ACF_FLAG_PTR(arm->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* metaball expander type define */
-static bAnimChannelType ACF_DSARM =
-{
- "Armature Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_dsarm_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dsarm_setting_flag, /* flag for setting */
- acf_dsarm_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSARM = {
+ "Armature Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dsarm_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dsarm_setting_flag, /* flag for setting */
+ acf_dsarm_setting_ptr, /* pointer for setting */
};
/* NodeTree Expander ------------------------------------------- */
@@ -2265,87 +2332,90 @@ static bAnimChannelType ACF_DSARM =
// TODO: just get this from RNA?
static int acf_dsntree_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_NODETREE;
+ return ICON_NODETREE;
}
/* offset for nodetree expanders */
static short acf_dsntree_offset(bAnimContext *ac, bAnimListElem *ale)
{
- bNodeTree *ntree = (bNodeTree *)ale->data;
- short offset = acf_generic_basic_offset(ac, ale);
+ bNodeTree *ntree = (bNodeTree *)ale->data;
+ short offset = acf_generic_basic_offset(ac, ale);
- offset += acf_nodetree_rootType_offset(ntree);
+ offset += acf_nodetree_rootType_offset(ntree);
- return offset;
+ return offset;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dsntree_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return NTREE_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return NTREE_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_dsntree_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
+static void *acf_dsntree_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings setting,
+ short *type)
{
- bNodeTree *ntree = (bNodeTree *)ale->data;
+ bNodeTree *ntree = (bNodeTree *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(ntree->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(ntree->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (ntree->adt)
- return GET_ACF_FLAG_PTR(ntree->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (ntree->adt)
+ return GET_ACF_FLAG_PTR(ntree->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* node tree expander type define */
-static bAnimChannelType ACF_DSNTREE =
-{
- "Node Tree Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_dsntree_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_dsntree_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dsntree_setting_flag, /* flag for setting */
- acf_dsntree_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSNTREE = {
+ "Node Tree Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_dsntree_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dsntree_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dsntree_setting_flag, /* flag for setting */
+ acf_dsntree_setting_ptr, /* pointer for setting */
};
/* LineStyle Expander ------------------------------------------- */
@@ -2353,76 +2423,79 @@ static bAnimChannelType ACF_DSNTREE =
/* TODO: just get this from RNA? */
static int acf_dslinestyle_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_LINE_DATA;
+ return ICON_LINE_DATA;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dslinestyle_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return LS_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return LS_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_dslinestyle_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
+static void *acf_dslinestyle_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings setting,
+ short *type)
{
- FreestyleLineStyle *linestyle = (FreestyleLineStyle *)ale->data;
+ FreestyleLineStyle *linestyle = (FreestyleLineStyle *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(linestyle->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(linestyle->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (linestyle->adt)
- return GET_ACF_FLAG_PTR(linestyle->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (linestyle->adt)
+ return GET_ACF_FLAG_PTR(linestyle->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* node tree expander type define */
-static bAnimChannelType ACF_DSLINESTYLE =
-{
- "Line Style Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop,/* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_dslinestyle_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dslinestyle_setting_flag, /* flag for setting */
- acf_dslinestyle_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSLINESTYLE = {
+ "Line Style Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dslinestyle_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dslinestyle_setting_flag, /* flag for setting */
+ acf_dslinestyle_setting_ptr, /* pointer for setting */
};
/* Mesh Expander ------------------------------------------- */
@@ -2430,76 +2503,78 @@ static bAnimChannelType ACF_DSLINESTYLE =
// TODO: just get this from RNA?
static int acf_dsmesh_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_MESH_DATA;
+ return ICON_MESH_DATA;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dsmesh_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return ME_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return ME_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
static void *acf_dsmesh_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- Mesh *me = (Mesh *)ale->data;
+ Mesh *me = (Mesh *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(me->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(me->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (me->adt)
- return GET_ACF_FLAG_PTR(me->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (me->adt)
+ return GET_ACF_FLAG_PTR(me->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* node tree expander type define */
-static bAnimChannelType ACF_DSMESH =
-{
- "Mesh Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */ // XXX this only works for compositing
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_dsmesh_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dsmesh_setting_flag, /* flag for setting */
- acf_dsmesh_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSMESH = {
+ "Mesh Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1,
+ /* indent level */ // XXX this only works for compositing
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dsmesh_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dsmesh_setting_flag, /* flag for setting */
+ acf_dsmesh_setting_ptr, /* pointer for setting */
};
/* Lattice Expander ------------------------------------------- */
@@ -2507,76 +2582,78 @@ static bAnimChannelType ACF_DSMESH =
// TODO: just get this from RNA?
static int acf_dslat_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_LATTICE_DATA;
+ return ICON_LATTICE_DATA;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dslat_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return LT_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return LT_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
static void *acf_dslat_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- Lattice *lt = (Lattice *)ale->data;
+ Lattice *lt = (Lattice *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(lt->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(lt->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (lt->adt)
- return GET_ACF_FLAG_PTR(lt->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (lt->adt)
+ return GET_ACF_FLAG_PTR(lt->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* node tree expander type define */
-static bAnimChannelType ACF_DSLAT =
-{
- "Lattice Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */ // XXX this only works for compositing
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_dslat_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dslat_setting_flag, /* flag for setting */
- acf_dslat_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSLAT = {
+ "Lattice Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1,
+ /* indent level */ // XXX this only works for compositing
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dslat_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dslat_setting_flag, /* flag for setting */
+ acf_dslat_setting_ptr, /* pointer for setting */
};
/* Speaker Expander ------------------------------------------- */
@@ -2584,76 +2661,77 @@ static bAnimChannelType ACF_DSLAT =
// TODO: just get this from RNA?
static int acf_dsspk_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_SPEAKER;
+ return ICON_SPEAKER;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dsspk_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return SPK_DS_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return SPK_DS_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
static void *acf_dsspk_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
{
- Speaker *spk = (Speaker *)ale->data;
+ Speaker *spk = (Speaker *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(spk->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(spk->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (spk->adt)
- return GET_ACF_FLAG_PTR(spk->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (spk->adt)
+ return GET_ACF_FLAG_PTR(spk->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* speaker expander type define */
-static bAnimChannelType ACF_DSSPK =
-{
- "Speaker Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_dsspk_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dsspk_setting_flag, /* flag for setting */
- acf_dsspk_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSSPK = {
+ "Speaker Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dsspk_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dsspk_setting_flag, /* flag for setting */
+ acf_dsspk_setting_ptr, /* pointer for setting */
};
/* GPencil Expander ------------------------------------------- */
@@ -2661,76 +2739,79 @@ static bAnimChannelType ACF_DSSPK =
// TODO: just get this from RNA?
static int acf_dsgpencil_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_GREASEPENCIL;
+ return ICON_GREASEPENCIL;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsgpencil_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dsgpencil_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GP_DATA_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GP_DATA_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_dsgpencil_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
+static void *acf_dsgpencil_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings setting,
+ short *type)
{
- bGPdata *gpd = (bGPdata *)ale->data;
+ bGPdata *gpd = (bGPdata *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(gpd->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(gpd->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (gpd->adt)
- return GET_ACF_FLAG_PTR(gpd->adt->flag, type);
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (gpd->adt)
+ return GET_ACF_FLAG_PTR(gpd->adt->flag, type);
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* grease pencil expander type define */
-static bAnimChannelType ACF_DSGPENCIL =
-{
- "GPencil DS Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idblock_name_prop, /* name prop */
- acf_dsgpencil_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dsgpencil_setting_flag, /* flag for setting */
- acf_dsgpencil_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSGPENCIL = {
+ "GPencil DS Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idblock_name_prop, /* name prop */
+ acf_dsgpencil_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dsgpencil_setting_flag, /* flag for setting */
+ acf_dsgpencil_setting_ptr, /* pointer for setting */
};
/* World Expander ------------------------------------------- */
@@ -2738,77 +2819,80 @@ static bAnimChannelType ACF_DSGPENCIL =
// TODO: just get this from RNA?
static int acf_dsmclip_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_SEQUENCE;
+ return ICON_SEQUENCE;
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_dsmclip_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_dsmclip_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return MCLIP_DATA_EXPAND;
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return MCLIP_DATA_EXPAND;
- case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
- return ADT_NLA_EVAL_OFF;
+ case ACHANNEL_SETTING_MUTE: /* mute (only in NLA) */
+ return ADT_NLA_EVAL_OFF;
- case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
- *neg = true;
- return ADT_CURVES_NOT_VISIBLE;
+ case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
+ *neg = true;
+ return ADT_CURVES_NOT_VISIBLE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return ADT_UI_SELECTED;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return ADT_UI_SELECTED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_dsmclip_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
+static void *acf_dsmclip_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings setting,
+ short *type)
{
- MovieClip *clip = (MovieClip *)ale->data;
+ MovieClip *clip = (MovieClip *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GET_ACF_FLAG_PTR(clip->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GET_ACF_FLAG_PTR(clip->flag, type);
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
- case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
- if (clip->adt != NULL) {
- return GET_ACF_FLAG_PTR(clip->adt->flag, type);
- }
- return NULL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
+ case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
+ if (clip->adt != NULL) {
+ return GET_ACF_FLAG_PTR(clip->adt->flag, type);
+ }
+ return NULL;
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* world expander type define */
-static bAnimChannelType ACF_DSMCLIP =
-{
- "Movieclip Expander", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_generic_dataexpand_color, /* backdrop color */
- acf_generic_dataexpand_backdrop, /* backdrop */
- acf_generic_indention_1, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idfill_name_prop, /* name prop */
- acf_dsmclip_icon, /* icon */
-
- acf_generic_dataexpand_setting_valid, /* has setting */
- acf_dsmclip_setting_flag, /* flag for setting */
- acf_dsmclip_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_DSMCLIP = {
+ "Movieclip Expander", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_generic_dataexpand_color, /* backdrop color */
+ acf_generic_dataexpand_backdrop, /* backdrop */
+ acf_generic_indention_1, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idfill_name_prop, /* name prop */
+ acf_dsmclip_icon, /* icon */
+
+ acf_generic_dataexpand_setting_valid, /* has setting */
+ acf_dsmclip_setting_flag, /* flag for setting */
+ acf_dsmclip_setting_ptr, /* pointer for setting */
};
/* ShapeKey Entry ------------------------------------------- */
@@ -2816,107 +2900,112 @@ static bAnimChannelType ACF_DSMCLIP =
/* name for ShapeKey */
static void acf_shapekey_name(bAnimListElem *ale, char *name)
{
- KeyBlock *kb = (KeyBlock *)ale->data;
+ KeyBlock *kb = (KeyBlock *)ale->data;
- /* just copy the name... */
- if (kb && name) {
- /* if the KeyBlock had a name, use it, otherwise use the index */
- if (kb->name[0])
- BLI_strncpy(name, kb->name, ANIM_CHAN_NAME_SIZE);
- else
- BLI_snprintf(name, ANIM_CHAN_NAME_SIZE, IFACE_("Key %d"), ale->index);
- }
+ /* just copy the name... */
+ if (kb && name) {
+ /* if the KeyBlock had a name, use it, otherwise use the index */
+ if (kb->name[0])
+ BLI_strncpy(name, kb->name, ANIM_CHAN_NAME_SIZE);
+ else
+ BLI_snprintf(name, ANIM_CHAN_NAME_SIZE, IFACE_("Key %d"), ale->index);
+ }
}
/* name property for ShapeKey entries */
static bool acf_shapekey_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
{
- KeyBlock *kb = (KeyBlock *)ale->data;
+ KeyBlock *kb = (KeyBlock *)ale->data;
- /* if the KeyBlock had a name, use it, otherwise use the index */
- if (kb && kb->name[0]) {
- RNA_pointer_create(ale->id, &RNA_ShapeKey, kb, ptr);
- *prop = RNA_struct_name_property(ptr->type);
+ /* if the KeyBlock had a name, use it, otherwise use the index */
+ if (kb && kb->name[0]) {
+ RNA_pointer_create(ale->id, &RNA_ShapeKey, kb, ptr);
+ *prop = RNA_struct_name_property(ptr->type);
- return (*prop != NULL);
- }
+ return (*prop != NULL);
+ }
- return false;
+ return false;
}
/* check if some setting exists for this channel */
-static bool acf_shapekey_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
+static bool acf_shapekey_setting_valid(bAnimContext *UNUSED(ac),
+ bAnimListElem *UNUSED(ale),
+ eAnimChannel_Settings setting)
{
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted */
- case ACHANNEL_SETTING_PROTECT: /* protected */
- return true;
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted */
+ case ACHANNEL_SETTING_PROTECT: /* protected */
+ return true;
- /* nothing else is supported */
- default:
- return false;
- }
+ /* nothing else is supported */
+ default:
+ return false;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_shapekey_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_MUTE: /* mute */
- return KEYBLOCK_MUTE;
+ switch (setting) {
+ case ACHANNEL_SETTING_MUTE: /* mute */
+ return KEYBLOCK_MUTE;
- case ACHANNEL_SETTING_SELECT: /* selected */
- return KEYBLOCK_SEL;
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return KEYBLOCK_SEL;
- case ACHANNEL_SETTING_PROTECT: /* locked */
- return KEYBLOCK_LOCKED;
+ case ACHANNEL_SETTING_PROTECT: /* locked */
+ return KEYBLOCK_LOCKED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_shapekey_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings setting, short *type)
+static void *acf_shapekey_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings setting,
+ short *type)
{
- KeyBlock *kb = (KeyBlock *)ale->data;
+ KeyBlock *kb = (KeyBlock *)ale->data;
- /* clear extra return data first */
- *type = 0;
+ /* clear extra return data first */
+ *type = 0;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- case ACHANNEL_SETTING_MUTE: /* muted */
- case ACHANNEL_SETTING_PROTECT: /* protected */
- return GET_ACF_FLAG_PTR(kb->flag, type);
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ case ACHANNEL_SETTING_MUTE: /* muted */
+ case ACHANNEL_SETTING_PROTECT: /* protected */
+ return GET_ACF_FLAG_PTR(kb->flag, type);
- default: /* unsupported */
- return NULL;
- }
+ default: /* unsupported */
+ return NULL;
+ }
}
/* shapekey expander type define */
-static bAnimChannelType ACF_SHAPEKEY =
-{
- "Shape Key", /* type name */
- ACHANNEL_ROLE_CHANNEL, /* role */
-
- acf_generic_channel_color, /* backdrop color */
- acf_generic_channel_backdrop, /* backdrop */
- acf_generic_indention_0, /* indent level */
- acf_generic_basic_offset, /* offset */
-
- acf_shapekey_name, /* name */
- acf_shapekey_name_prop, /* name prop */
- NULL, /* icon */
-
- acf_shapekey_setting_valid, /* has setting */
- acf_shapekey_setting_flag, /* flag for setting */
- acf_shapekey_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_SHAPEKEY = {
+ "Shape Key", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
+
+ acf_generic_channel_color, /* backdrop color */
+ acf_generic_channel_backdrop, /* backdrop */
+ acf_generic_indention_0, /* indent level */
+ acf_generic_basic_offset, /* offset */
+
+ acf_shapekey_name, /* name */
+ acf_shapekey_name_prop, /* name prop */
+ NULL, /* icon */
+
+ acf_shapekey_setting_valid, /* has setting */
+ acf_shapekey_setting_flag, /* flag for setting */
+ acf_shapekey_setting_ptr, /* pointer for setting */
};
/* GPencil Datablock ------------------------------------------- */
@@ -2924,76 +3013,79 @@ static bAnimChannelType ACF_SHAPEKEY =
/* get backdrop color for gpencil datablock widget */
static void acf_gpd_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3])
{
- /* these are ID-blocks, but not exactly standalone... */
- UI_GetThemeColorShade3fv(TH_DOPESHEET_CHANNELSUBOB, 20, r_color);
+ /* these are ID-blocks, but not exactly standalone... */
+ UI_GetThemeColorShade3fv(TH_DOPESHEET_CHANNELSUBOB, 20, r_color);
}
// TODO: just get this from RNA?
static int acf_gpd_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_GREASEPENCIL;
+ return ICON_GREASEPENCIL;
}
/* check if some setting exists for this channel */
-static bool acf_gpd_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
+static bool acf_gpd_setting_valid(bAnimContext *UNUSED(ac),
+ bAnimListElem *UNUSED(ale),
+ eAnimChannel_Settings setting)
{
- switch (setting) {
- /* only select and expand supported */
- case ACHANNEL_SETTING_SELECT:
- case ACHANNEL_SETTING_EXPAND:
- return true;
+ switch (setting) {
+ /* only select and expand supported */
+ case ACHANNEL_SETTING_SELECT:
+ case ACHANNEL_SETTING_EXPAND:
+ return true;
- default:
- return false;
- }
+ default:
+ return false;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
static int acf_gpd_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- return AGRP_SELECTED;
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return AGRP_SELECTED;
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return GP_DATA_EXPAND;
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return GP_DATA_EXPAND;
- default:
- /* these shouldn't happen */
- return 0;
- }
+ default:
+ /* these shouldn't happen */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_gpd_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
+static void *acf_gpd_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings UNUSED(setting),
+ short *type)
{
- bGPdata *gpd = (bGPdata *)ale->data;
+ bGPdata *gpd = (bGPdata *)ale->data;
- /* all flags are just in gpd->flag for now... */
- return GET_ACF_FLAG_PTR(gpd->flag, type);
+ /* all flags are just in gpd->flag for now... */
+ return GET_ACF_FLAG_PTR(gpd->flag, type);
}
/* gpencil datablock type define */
-static bAnimChannelType ACF_GPD =
-{
- "GPencil Datablock", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_gpd_color, /* backdrop color */
- acf_group_backdrop, /* backdrop */
- acf_generic_indention_0, /* indent level */
- acf_generic_group_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idfill_name_prop, /* name prop */
- acf_gpd_icon, /* icon */
-
- acf_gpd_setting_valid, /* has setting */
- acf_gpd_setting_flag, /* flag for setting */
- acf_gpd_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_GPD = {
+ "GPencil Datablock", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_gpd_color, /* backdrop color */
+ acf_group_backdrop, /* backdrop */
+ acf_generic_indention_0, /* indent level */
+ acf_generic_group_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idfill_name_prop, /* name prop */
+ acf_gpd_icon, /* icon */
+
+ acf_gpd_setting_valid, /* has setting */
+ acf_gpd_setting_flag, /* flag for setting */
+ acf_gpd_setting_ptr, /* pointer for setting */
};
/* GPencil Layer ------------------------------------------- */
@@ -3001,170 +3093,177 @@ static bAnimChannelType ACF_GPD =
/* name for grease pencil layer entries */
static void acf_gpl_name(bAnimListElem *ale, char *name)
{
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
- if (gpl && name)
- BLI_strncpy(name, gpl->info, ANIM_CHAN_NAME_SIZE);
+ if (gpl && name)
+ BLI_strncpy(name, gpl->info, ANIM_CHAN_NAME_SIZE);
}
/* name property for grease pencil layer entries */
static bool acf_gpl_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
{
- if (ale->data) {
- RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, ptr);
- *prop = RNA_struct_name_property(ptr->type);
+ if (ale->data) {
+ RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, ptr);
+ *prop = RNA_struct_name_property(ptr->type);
- return (*prop != NULL);
- }
+ return (*prop != NULL);
+ }
- return false;
+ return false;
}
/* check if some setting exists for this channel */
-static bool acf_gpl_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
+static bool acf_gpl_setting_valid(bAnimContext *UNUSED(ac),
+ bAnimListElem *UNUSED(ale),
+ eAnimChannel_Settings setting)
{
- switch (setting) {
- /* unsupported */
- case ACHANNEL_SETTING_EXPAND: /* gpencil layers are more like F-Curves than groups */
- case ACHANNEL_SETTING_SOLO: /* nla editor only */
- return false;
+ switch (setting) {
+ /* unsupported */
+ case ACHANNEL_SETTING_EXPAND: /* gpencil layers are more like F-Curves than groups */
+ case ACHANNEL_SETTING_SOLO: /* nla editor only */
+ return false;
- /* always available */
- default:
- return true;
- }
+ /* always available */
+ default:
+ return true;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
static int acf_gpl_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- return GP_LAYER_SELECT;
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return GP_LAYER_SELECT;
- case ACHANNEL_SETTING_MUTE: /* animation muting - similar to frame lock... */
- return GP_LAYER_FRAMELOCK;
+ case ACHANNEL_SETTING_MUTE: /* animation muting - similar to frame lock... */
+ return GP_LAYER_FRAMELOCK;
- case ACHANNEL_SETTING_VISIBLE: /* visibility of the layers (NOT muting) */
- *neg = true;
- return GP_LAYER_HIDE;
+ case ACHANNEL_SETTING_VISIBLE: /* visibility of the layers (NOT muting) */
+ *neg = true;
+ return GP_LAYER_HIDE;
- case ACHANNEL_SETTING_PROTECT: /* protected */
- return GP_LAYER_LOCKED;
+ case ACHANNEL_SETTING_PROTECT: /* protected */
+ return GP_LAYER_LOCKED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_gpl_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
+static void *acf_gpl_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings UNUSED(setting),
+ short *type)
{
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
- /* all flags are just in gpl->flag for now... */
- return GET_ACF_FLAG_PTR(gpl->flag, type);
+ /* all flags are just in gpl->flag for now... */
+ return GET_ACF_FLAG_PTR(gpl->flag, type);
}
/* grease pencil layer type define */
-static bAnimChannelType ACF_GPL =
-{
- "GPencil Layer", /* type name */
- ACHANNEL_ROLE_CHANNEL, /* role */
-
- acf_gpencil_channel_color, /* backdrop color */
- acf_generic_channel_backdrop, /* backdrop */
- acf_generic_indention_flexible, /* indent level */
- acf_generic_group_offset, /* offset */
-
- acf_gpl_name, /* name */
- acf_gpl_name_prop, /* name prop */
- NULL, /* icon */
-
- acf_gpl_setting_valid, /* has setting */
- acf_gpl_setting_flag, /* flag for setting */
- acf_gpl_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_GPL = {
+ "GPencil Layer", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
+
+ acf_gpencil_channel_color, /* backdrop color */
+ acf_generic_channel_backdrop, /* backdrop */
+ acf_generic_indention_flexible, /* indent level */
+ acf_generic_group_offset, /* offset */
+
+ acf_gpl_name, /* name */
+ acf_gpl_name_prop, /* name prop */
+ NULL, /* icon */
+
+ acf_gpl_setting_valid, /* has setting */
+ acf_gpl_setting_flag, /* flag for setting */
+ acf_gpl_setting_ptr, /* pointer for setting */
};
-
/* Mask Datablock ------------------------------------------- */
/* get backdrop color for mask datablock widget */
static void acf_mask_color(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), float r_color[3])
{
- /* these are ID-blocks, but not exactly standalone... */
- UI_GetThemeColorShade3fv(TH_DOPESHEET_CHANNELSUBOB, 20, r_color);
+ /* these are ID-blocks, but not exactly standalone... */
+ UI_GetThemeColorShade3fv(TH_DOPESHEET_CHANNELSUBOB, 20, r_color);
}
// TODO: just get this from RNA?
static int acf_mask_icon(bAnimListElem *UNUSED(ale))
{
- return ICON_MOD_MASK;
+ return ICON_MOD_MASK;
}
/* check if some setting exists for this channel */
-static bool acf_mask_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
+static bool acf_mask_setting_valid(bAnimContext *UNUSED(ac),
+ bAnimListElem *UNUSED(ale),
+ eAnimChannel_Settings setting)
{
- switch (setting) {
- /* only select and expand supported */
- case ACHANNEL_SETTING_SELECT:
- case ACHANNEL_SETTING_EXPAND:
- return true;
+ switch (setting) {
+ /* only select and expand supported */
+ case ACHANNEL_SETTING_SELECT:
+ case ACHANNEL_SETTING_EXPAND:
+ return true;
- default:
- return false;
- }
+ default:
+ return false;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_mask_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- return AGRP_SELECTED;
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return AGRP_SELECTED;
- case ACHANNEL_SETTING_EXPAND: /* expanded */
- return MASK_ANIMF_EXPAND;
+ case ACHANNEL_SETTING_EXPAND: /* expanded */
+ return MASK_ANIMF_EXPAND;
- default:
- /* this shouldn't happen */
- return 0;
- }
+ default:
+ /* this shouldn't happen */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_mask_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
+static void *acf_mask_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings UNUSED(setting),
+ short *type)
{
- Mask *mask = (Mask *)ale->data;
+ Mask *mask = (Mask *)ale->data;
- /* all flags are just in mask->flag for now... */
- return GET_ACF_FLAG_PTR(mask->flag, type);
+ /* all flags are just in mask->flag for now... */
+ return GET_ACF_FLAG_PTR(mask->flag, type);
}
/* mask datablock type define */
-static bAnimChannelType ACF_MASKDATA =
-{
- "Mask Datablock", /* type name */
- ACHANNEL_ROLE_EXPANDER, /* role */
-
- acf_mask_color, /* backdrop color */
- acf_group_backdrop, /* backdrop */
- acf_generic_indention_0, /* indent level */
- acf_generic_group_offset, /* offset */
-
- acf_generic_idblock_name, /* name */
- acf_generic_idfill_name_prop, /* name prop */
- acf_mask_icon, /* icon */
-
- acf_mask_setting_valid, /* has setting */
- acf_mask_setting_flag, /* flag for setting */
- acf_mask_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_MASKDATA = {
+ "Mask Datablock", /* type name */
+ ACHANNEL_ROLE_EXPANDER, /* role */
+
+ acf_mask_color, /* backdrop color */
+ acf_group_backdrop, /* backdrop */
+ acf_generic_indention_0, /* indent level */
+ acf_generic_group_offset, /* offset */
+
+ acf_generic_idblock_name, /* name */
+ acf_generic_idfill_name_prop, /* name prop */
+ acf_mask_icon, /* icon */
+
+ acf_mask_setting_valid, /* has setting */
+ acf_mask_setting_flag, /* flag for setting */
+ acf_mask_setting_ptr, /* pointer for setting */
};
/* Mask Layer ------------------------------------------- */
@@ -3172,86 +3271,91 @@ static bAnimChannelType ACF_MASKDATA =
/* name for grease pencil layer entries */
static void acf_masklay_name(bAnimListElem *ale, char *name)
{
- MaskLayer *masklay = (MaskLayer *)ale->data;
+ MaskLayer *masklay = (MaskLayer *)ale->data;
- if (masklay && name)
- BLI_strncpy(name, masklay->name, ANIM_CHAN_NAME_SIZE);
+ if (masklay && name)
+ BLI_strncpy(name, masklay->name, ANIM_CHAN_NAME_SIZE);
}
/* name property for grease pencil layer entries */
static bool acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
{
- if (ale->data) {
- RNA_pointer_create(ale->id, &RNA_MaskLayer, ale->data, ptr);
- *prop = RNA_struct_name_property(ptr->type);
+ if (ale->data) {
+ RNA_pointer_create(ale->id, &RNA_MaskLayer, ale->data, ptr);
+ *prop = RNA_struct_name_property(ptr->type);
- return (*prop != NULL);
- }
+ return (*prop != NULL);
+ }
- return false;
+ return false;
}
/* check if some setting exists for this channel */
-static bool acf_masklay_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNUSED(ale), eAnimChannel_Settings setting)
+static bool acf_masklay_setting_valid(bAnimContext *UNUSED(ac),
+ bAnimListElem *UNUSED(ale),
+ eAnimChannel_Settings setting)
{
- switch (setting) {
- /* unsupported */
- case ACHANNEL_SETTING_EXPAND: /* mask layers are more like F-Curves than groups */
- case ACHANNEL_SETTING_VISIBLE: /* graph editor only */
- case ACHANNEL_SETTING_SOLO: /* nla editor only */
- return false;
+ switch (setting) {
+ /* unsupported */
+ case ACHANNEL_SETTING_EXPAND: /* mask layers are more like F-Curves than groups */
+ case ACHANNEL_SETTING_VISIBLE: /* graph editor only */
+ case ACHANNEL_SETTING_SOLO: /* nla editor only */
+ return false;
- /* always available */
- default:
- return true;
- }
+ /* always available */
+ default:
+ return true;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- return MASK_LAYERFLAG_SELECT;
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return MASK_LAYERFLAG_SELECT;
- case ACHANNEL_SETTING_PROTECT: /* protected */
- return MASK_LAYERFLAG_LOCKED;
+ case ACHANNEL_SETTING_PROTECT: /* protected */
+ return MASK_LAYERFLAG_LOCKED;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_masklay_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
+static void *acf_masklay_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings UNUSED(setting),
+ short *type)
{
- MaskLayer *masklay = (MaskLayer *)ale->data;
+ MaskLayer *masklay = (MaskLayer *)ale->data;
- /* all flags are just in masklay->flag for now... */
- return GET_ACF_FLAG_PTR(masklay->flag, type);
+ /* all flags are just in masklay->flag for now... */
+ return GET_ACF_FLAG_PTR(masklay->flag, type);
}
/* grease pencil layer type define */
-static bAnimChannelType ACF_MASKLAYER =
-{
- "Mask Layer", /* type name */
- ACHANNEL_ROLE_CHANNEL, /* role */
-
- acf_generic_channel_color, /* backdrop color */
- acf_generic_channel_backdrop, /* backdrop */
- acf_generic_indention_flexible, /* indent level */
- acf_generic_group_offset, /* offset */
-
- acf_masklay_name, /* name */
- acf_masklay_name_prop, /* name prop */
- NULL, /* icon */
-
- acf_masklay_setting_valid, /* has setting */
- acf_masklay_setting_flag, /* flag for setting */
- acf_masklay_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_MASKLAYER = {
+ "Mask Layer", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
+
+ acf_generic_channel_color, /* backdrop color */
+ acf_generic_channel_backdrop, /* backdrop */
+ acf_generic_indention_flexible, /* indent level */
+ acf_generic_group_offset, /* offset */
+
+ acf_masklay_name, /* name */
+ acf_masklay_name_prop, /* name prop */
+ NULL, /* icon */
+
+ acf_masklay_setting_valid, /* has setting */
+ acf_masklay_setting_flag, /* flag for setting */
+ acf_masklay_setting_ptr, /* pointer for setting */
};
/* NLA Track ----------------------------------------------- */
@@ -3259,138 +3363,143 @@ static bAnimChannelType ACF_MASKLAYER =
/* get backdrop color for nla track channels */
static void acf_nlatrack_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, float r_color[3])
{
- NlaTrack *nlt = (NlaTrack *)ale->data;
- AnimData *adt = ale->adt;
- bool nonSolo = false;
+ NlaTrack *nlt = (NlaTrack *)ale->data;
+ AnimData *adt = ale->adt;
+ bool nonSolo = false;
- /* is track enabled for solo drawing? */
- if ((adt) && (adt->flag & ADT_NLA_SOLO_TRACK)) {
- if ((nlt->flag & NLATRACK_SOLO) == 0) {
- /* tag for special non-solo handling */
- nonSolo = true;
- }
- }
+ /* is track enabled for solo drawing? */
+ if ((adt) && (adt->flag & ADT_NLA_SOLO_TRACK)) {
+ if ((nlt->flag & NLATRACK_SOLO) == 0) {
+ /* tag for special non-solo handling */
+ nonSolo = true;
+ }
+ }
- /* set color for nla track */
- UI_GetThemeColorShade3fv(TH_HEADER, ((nonSolo == false) ? 20 : -20), r_color);
+ /* set color for nla track */
+ UI_GetThemeColorShade3fv(TH_HEADER, ((nonSolo == false) ? 20 : -20), r_color);
}
/* name for nla track entries */
static void acf_nlatrack_name(bAnimListElem *ale, char *name)
{
- NlaTrack *nlt = (NlaTrack *)ale->data;
+ NlaTrack *nlt = (NlaTrack *)ale->data;
- if (nlt && name)
- BLI_strncpy(name, nlt->name, ANIM_CHAN_NAME_SIZE);
+ if (nlt && name)
+ BLI_strncpy(name, nlt->name, ANIM_CHAN_NAME_SIZE);
}
/* name property for nla track entries */
static bool acf_nlatrack_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
{
- if (ale->data) {
- RNA_pointer_create(ale->id, &RNA_NlaTrack, ale->data, ptr);
- *prop = RNA_struct_name_property(ptr->type);
+ if (ale->data) {
+ RNA_pointer_create(ale->id, &RNA_NlaTrack, ale->data, ptr);
+ *prop = RNA_struct_name_property(ptr->type);
- return (*prop != NULL);
- }
+ return (*prop != NULL);
+ }
- return false;
+ return false;
}
/* check if some setting exists for this channel */
-static bool acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *ale, eAnimChannel_Settings setting)
-{
- NlaTrack *nlt = (NlaTrack *)ale->data;
- AnimData *adt = ale->adt;
-
- /* visibility of settings depends on various states... */
- switch (setting) {
- /* always supported */
- case ACHANNEL_SETTING_SELECT:
- case ACHANNEL_SETTING_SOLO:
- return true;
-
- /* conditionally supported... */
- case ACHANNEL_SETTING_PROTECT:
- case ACHANNEL_SETTING_MUTE:
- /* if this track is active and we're tweaking it, don't draw these toggles */
- if (((nlt->flag & NLATRACK_ACTIVE) && (nlt->flag & NLATRACK_DISABLED)) == 0) {
- /* is track enabled for solo drawing? */
- if ((adt) && (adt->flag & ADT_NLA_SOLO_TRACK)) {
- if (nlt->flag & NLATRACK_SOLO) {
- /* ok - we've got a solo track, and this is it */
- return true;
- }
- else {
- /* not ok - we've got a solo track, but this isn't it, so make it more obvious */
- return false;
- }
- }
-
-
- /* ok - no tracks are solo'd, and this isn't being tweaked */
- return true;
- }
- else {
- /* unsupported - this track is being tweaked */
- return false;
- }
-
- /* unsupported */
- default:
- return false;
- }
+static bool acf_nlatrack_setting_valid(bAnimContext *UNUSED(ac),
+ bAnimListElem *ale,
+ eAnimChannel_Settings setting)
+{
+ NlaTrack *nlt = (NlaTrack *)ale->data;
+ AnimData *adt = ale->adt;
+
+ /* visibility of settings depends on various states... */
+ switch (setting) {
+ /* always supported */
+ case ACHANNEL_SETTING_SELECT:
+ case ACHANNEL_SETTING_SOLO:
+ return true;
+
+ /* conditionally supported... */
+ case ACHANNEL_SETTING_PROTECT:
+ case ACHANNEL_SETTING_MUTE:
+ /* if this track is active and we're tweaking it, don't draw these toggles */
+ if (((nlt->flag & NLATRACK_ACTIVE) && (nlt->flag & NLATRACK_DISABLED)) == 0) {
+ /* is track enabled for solo drawing? */
+ if ((adt) && (adt->flag & ADT_NLA_SOLO_TRACK)) {
+ if (nlt->flag & NLATRACK_SOLO) {
+ /* ok - we've got a solo track, and this is it */
+ return true;
+ }
+ else {
+ /* not ok - we've got a solo track, but this isn't it, so make it more obvious */
+ return false;
+ }
+ }
+
+ /* ok - no tracks are solo'd, and this isn't being tweaked */
+ return true;
+ }
+ else {
+ /* unsupported - this track is being tweaked */
+ return false;
+ }
+
+ /* unsupported */
+ default:
+ return false;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_nlatrack_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_nlatrack_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_SELECT: /* selected */
- return NLATRACK_SELECTED;
+ switch (setting) {
+ case ACHANNEL_SETTING_SELECT: /* selected */
+ return NLATRACK_SELECTED;
- case ACHANNEL_SETTING_MUTE: /* muted */
- return NLATRACK_MUTED;
+ case ACHANNEL_SETTING_MUTE: /* muted */
+ return NLATRACK_MUTED;
- case ACHANNEL_SETTING_PROTECT: /* protected */
- return NLATRACK_PROTECTED;
+ case ACHANNEL_SETTING_PROTECT: /* protected */
+ return NLATRACK_PROTECTED;
- case ACHANNEL_SETTING_SOLO: /* solo */
- return NLATRACK_SOLO;
+ case ACHANNEL_SETTING_SOLO: /* solo */
+ return NLATRACK_SOLO;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_nlatrack_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
+static void *acf_nlatrack_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings UNUSED(setting),
+ short *type)
{
- NlaTrack *nlt = (NlaTrack *)ale->data;
- return GET_ACF_FLAG_PTR(nlt->flag, type);
+ NlaTrack *nlt = (NlaTrack *)ale->data;
+ return GET_ACF_FLAG_PTR(nlt->flag, type);
}
/* nla track type define */
-static bAnimChannelType ACF_NLATRACK =
-{
- "NLA Track", /* type name */
- ACHANNEL_ROLE_CHANNEL, /* role */
-
- acf_nlatrack_color, /* backdrop color */
- acf_generic_channel_backdrop, /* backdrop */
- acf_generic_indention_flexible, /* indent level */
- acf_generic_group_offset, /* offset */ // XXX?
-
- acf_nlatrack_name, /* name */
- acf_nlatrack_name_prop, /* name prop */
- NULL, /* icon */
-
- acf_nlatrack_setting_valid, /* has setting */
- acf_nlatrack_setting_flag, /* flag for setting */
- acf_nlatrack_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_NLATRACK = {
+ "NLA Track", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
+
+ acf_nlatrack_color, /* backdrop color */
+ acf_generic_channel_backdrop, /* backdrop */
+ acf_generic_indention_flexible, /* indent level */
+ acf_generic_group_offset,
+ /* offset */ // XXX?
+
+ acf_nlatrack_name, /* name */
+ acf_nlatrack_name_prop, /* name prop */
+ NULL, /* icon */
+
+ acf_nlatrack_setting_valid, /* has setting */
+ acf_nlatrack_setting_flag, /* flag for setting */
+ acf_nlatrack_setting_ptr, /* pointer for setting */
};
/* NLA Action ----------------------------------------------- */
@@ -3398,15 +3507,15 @@ static bAnimChannelType ACF_NLATRACK =
/* icon for action depends on whether it's in tweaking mode */
static int acf_nlaaction_icon(bAnimListElem *ale)
{
- AnimData *adt = ale->adt;
+ AnimData *adt = ale->adt;
- /* indicate tweaking-action state by changing the icon... */
- if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
- return ICON_ACTION_TWEAK;
- }
- else {
- return ICON_ACTION;
- }
+ /* indicate tweaking-action state by changing the icon... */
+ if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
+ return ICON_ACTION_TWEAK;
+ }
+ else {
+ return ICON_ACTION;
+ }
}
/* Backdrop color for nla action channel
@@ -3415,151 +3524,162 @@ static int acf_nlaaction_icon(bAnimListElem *ale)
*/
static void acf_nlaaction_color(bAnimContext *UNUSED(ac), bAnimListElem *ale, float r_color[3])
{
- float color[4];
+ float color[4];
- /* Action Line
- * The alpha values action_get_color returns are only useful for drawing
- * strips backgrounds but here we're doing channel list backgrounds instead
- * so we ignore that and use our own when needed
- */
- nla_action_get_color(ale->adt, (bAction *)ale->data, color);
+ /* Action Line
+ * The alpha values action_get_color returns are only useful for drawing
+ * strips backgrounds but here we're doing channel list backgrounds instead
+ * so we ignore that and use our own when needed
+ */
+ nla_action_get_color(ale->adt, (bAction *)ale->data, color);
- /* NOTE: since the return types only allow rgb, we cannot do the alpha-blending we'd
- * like for the solo-drawing case. Hence, this method isn't actually used for drawing
- * most of the channel...
- */
- copy_v3_v3(r_color, color);
+ /* NOTE: since the return types only allow rgb, we cannot do the alpha-blending we'd
+ * like for the solo-drawing case. Hence, this method isn't actually used for drawing
+ * most of the channel...
+ */
+ copy_v3_v3(r_color, color);
}
/* backdrop for nla action channel */
static void acf_nlaaction_backdrop(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc)
{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- View2D *v2d = &ac->ar->v2d;
- AnimData *adt = ale->adt;
- short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
- float color[4];
-
- /* Action Line
- * The alpha values action_get_color returns are only useful for drawing
- * strips backgrounds but here we're doing channel list backgrounds instead
- * so we ignore that and use our own when needed
- */
- nla_action_get_color(adt, (bAction *)ale->data, color);
-
- if (adt && (adt->flag & ADT_NLA_EDIT_ON))
- color[3] = 1.0f;
- else
- color[3] = (adt && (adt->flag & ADT_NLA_SOLO_TRACK)) ? 0.3f : 1.0f;
-
- /* only on top left corner, to show that this channel sits on top of the preceding ones
- * while still linking into the action line strip to the right
- */
- UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT);
-
- /* draw slightly shifted up vertically to look like it has more separation from other channels,
- * but we then need to slightly shorten it so that it doesn't look like it overlaps
- */
- UI_draw_roundbox_4fv(true, offset, yminc + NLACHANNEL_SKIP, (float)v2d->cur.xmax, ymaxc + NLACHANNEL_SKIP - 1, 8, color);
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ View2D *v2d = &ac->ar->v2d;
+ AnimData *adt = ale->adt;
+ short offset = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+ float color[4];
+
+ /* Action Line
+ * The alpha values action_get_color returns are only useful for drawing
+ * strips backgrounds but here we're doing channel list backgrounds instead
+ * so we ignore that and use our own when needed
+ */
+ nla_action_get_color(adt, (bAction *)ale->data, color);
+
+ if (adt && (adt->flag & ADT_NLA_EDIT_ON))
+ color[3] = 1.0f;
+ else
+ color[3] = (adt && (adt->flag & ADT_NLA_SOLO_TRACK)) ? 0.3f : 1.0f;
+
+ /* only on top left corner, to show that this channel sits on top of the preceding ones
+ * while still linking into the action line strip to the right
+ */
+ UI_draw_roundbox_corner_set(UI_CNR_TOP_LEFT);
+
+ /* draw slightly shifted up vertically to look like it has more separation from other channels,
+ * but we then need to slightly shorten it so that it doesn't look like it overlaps
+ */
+ UI_draw_roundbox_4fv(true,
+ offset,
+ yminc + NLACHANNEL_SKIP,
+ (float)v2d->cur.xmax,
+ ymaxc + NLACHANNEL_SKIP - 1,
+ 8,
+ color);
}
/* name for nla action entries */
static void acf_nlaaction_name(bAnimListElem *ale, char *name)
{
- bAction *act = (bAction *)ale->data;
+ bAction *act = (bAction *)ale->data;
- if (name) {
- if (act) {
- // TODO: add special decoration when doing this in tweaking mode?
- BLI_strncpy(name, act->id.name + 2, ANIM_CHAN_NAME_SIZE);
- }
- else {
- BLI_strncpy(name, "<No Action>", ANIM_CHAN_NAME_SIZE);
- }
- }
+ if (name) {
+ if (act) {
+ // TODO: add special decoration when doing this in tweaking mode?
+ BLI_strncpy(name, act->id.name + 2, ANIM_CHAN_NAME_SIZE);
+ }
+ else {
+ BLI_strncpy(name, "<No Action>", ANIM_CHAN_NAME_SIZE);
+ }
+ }
}
/* name property for nla action entries */
static bool acf_nlaaction_name_prop(bAnimListElem *ale, PointerRNA *ptr, PropertyRNA **prop)
{
- if (ale->data) {
- RNA_pointer_create(ale->id, &RNA_Action, ale->data, ptr);
- *prop = RNA_struct_name_property(ptr->type);
+ if (ale->data) {
+ RNA_pointer_create(ale->id, &RNA_Action, ale->data, ptr);
+ *prop = RNA_struct_name_property(ptr->type);
- return (*prop != NULL);
- }
+ return (*prop != NULL);
+ }
- return false;
+ return false;
}
/* check if some setting exists for this channel */
-static bool acf_nlaaction_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *ale, eAnimChannel_Settings setting)
-{
- AnimData *adt = ale->adt;
-
- /* visibility of settings depends on various states... */
- switch (setting) {
- /* conditionally supported */
- case ACHANNEL_SETTING_PINNED: /* pinned - map/unmap */
- if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
- /* this should only appear in tweakmode */
- return true;
- }
- else {
- return false;
- }
-
- /* unsupported */
- default:
- return false;
- }
+static bool acf_nlaaction_setting_valid(bAnimContext *UNUSED(ac),
+ bAnimListElem *ale,
+ eAnimChannel_Settings setting)
+{
+ AnimData *adt = ale->adt;
+
+ /* visibility of settings depends on various states... */
+ switch (setting) {
+ /* conditionally supported */
+ case ACHANNEL_SETTING_PINNED: /* pinned - map/unmap */
+ if ((adt) && (adt->flag & ADT_NLA_EDIT_ON)) {
+ /* this should only appear in tweakmode */
+ return true;
+ }
+ else {
+ return false;
+ }
+
+ /* unsupported */
+ default:
+ return false;
+ }
}
/* get the appropriate flag(s) for the setting when it is valid */
-static int acf_nlaaction_setting_flag(bAnimContext *UNUSED(ac), eAnimChannel_Settings setting, bool *neg)
+static int acf_nlaaction_setting_flag(bAnimContext *UNUSED(ac),
+ eAnimChannel_Settings setting,
+ bool *neg)
{
- /* clear extra return data first */
- *neg = false;
+ /* clear extra return data first */
+ *neg = false;
- switch (setting) {
- case ACHANNEL_SETTING_PINNED: /* pinned - map/unmap */
- *neg = true; // XXX
- return ADT_NLA_EDIT_NOMAP;
+ switch (setting) {
+ case ACHANNEL_SETTING_PINNED: /* pinned - map/unmap */
+ *neg = true; // XXX
+ return ADT_NLA_EDIT_NOMAP;
- default: /* unsupported */
- return 0;
- }
+ default: /* unsupported */
+ return 0;
+ }
}
/* get pointer to the setting */
-static void *acf_nlaaction_setting_ptr(bAnimListElem *ale, eAnimChannel_Settings UNUSED(setting), short *type)
+static void *acf_nlaaction_setting_ptr(bAnimListElem *ale,
+ eAnimChannel_Settings UNUSED(setting),
+ short *type)
{
- AnimData *adt = ale->adt;
- return GET_ACF_FLAG_PTR(adt->flag, type);
+ AnimData *adt = ale->adt;
+ return GET_ACF_FLAG_PTR(adt->flag, type);
}
/* nla action type define */
-static bAnimChannelType ACF_NLAACTION =
-{
- "NLA Active Action", /* type name */
- ACHANNEL_ROLE_CHANNEL, /* role */
-
- acf_nlaaction_color, /* backdrop color (NOTE: the backdrop handles this too,
- * since it needs special hacks) */
- acf_nlaaction_backdrop, /* backdrop */
- acf_generic_indention_flexible, /* indent level */
- acf_generic_group_offset, /* offset */ // XXX?
-
- acf_nlaaction_name, /* name */
- acf_nlaaction_name_prop, /* name prop */
- acf_nlaaction_icon, /* icon */
-
- acf_nlaaction_setting_valid, /* has setting */
- acf_nlaaction_setting_flag, /* flag for setting */
- acf_nlaaction_setting_ptr, /* pointer for setting */
+static bAnimChannelType ACF_NLAACTION = {
+ "NLA Active Action", /* type name */
+ ACHANNEL_ROLE_CHANNEL, /* role */
+
+ acf_nlaaction_color, /* backdrop color (NOTE: the backdrop handles this too,
+ * since it needs special hacks) */
+ acf_nlaaction_backdrop, /* backdrop */
+ acf_generic_indention_flexible, /* indent level */
+ acf_generic_group_offset,
+ /* offset */ // XXX?
+
+ acf_nlaaction_name, /* name */
+ acf_nlaaction_name_prop, /* name prop */
+ acf_nlaaction_icon, /* icon */
+
+ acf_nlaaction_setting_valid, /* has setting */
+ acf_nlaaction_setting_flag, /* flag for setting */
+ acf_nlaaction_setting_ptr, /* pointer for setting */
};
-
/* *********************************************** */
/* Type Registration and General Access */
@@ -3570,79 +3690,79 @@ static short ACF_INIT = 1; /* when non-zero, the list needs to be updated */
/* Initialize type info definitions */
static void ANIM_init_channel_typeinfo_data(void)
{
- int type = 0;
+ int type = 0;
- /* start initializing if necessary... */
- if (ACF_INIT) {
- ACF_INIT = 0;
+ /* start initializing if necessary... */
+ if (ACF_INIT) {
+ ACF_INIT = 0;
- /* NOTE: need to keep the order of these synchronized with the definition of
- * channel types (eAnim_ChannelType) in ED_anim_api.h
- */
- animchannelTypeInfo[type++] = NULL; /* None */
- animchannelTypeInfo[type++] = NULL; /* AnimData */
- animchannelTypeInfo[type++] = NULL; /* Special */
+ /* NOTE: need to keep the order of these synchronized with the definition of
+ * channel types (eAnim_ChannelType) in ED_anim_api.h
+ */
+ animchannelTypeInfo[type++] = NULL; /* None */
+ animchannelTypeInfo[type++] = NULL; /* AnimData */
+ animchannelTypeInfo[type++] = NULL; /* Special */
- animchannelTypeInfo[type++] = &ACF_SUMMARY; /* Motion Summary */
+ animchannelTypeInfo[type++] = &ACF_SUMMARY; /* Motion Summary */
- animchannelTypeInfo[type++] = &ACF_SCENE; /* Scene */
- animchannelTypeInfo[type++] = &ACF_OBJECT; /* Object */
- animchannelTypeInfo[type++] = &ACF_GROUP; /* Group */
- animchannelTypeInfo[type++] = &ACF_FCURVE; /* F-Curve */
+ animchannelTypeInfo[type++] = &ACF_SCENE; /* Scene */
+ animchannelTypeInfo[type++] = &ACF_OBJECT; /* Object */
+ animchannelTypeInfo[type++] = &ACF_GROUP; /* Group */
+ animchannelTypeInfo[type++] = &ACF_FCURVE; /* F-Curve */
- animchannelTypeInfo[type++] = &ACF_NLACONTROLS; /* NLA Control FCurve Expander */
- animchannelTypeInfo[type++] = &ACF_NLACURVE; /* NLA Control FCurve Channel */
+ animchannelTypeInfo[type++] = &ACF_NLACONTROLS; /* NLA Control FCurve Expander */
+ animchannelTypeInfo[type++] = &ACF_NLACURVE; /* NLA Control FCurve Channel */
- animchannelTypeInfo[type++] = &ACF_FILLACTD; /* Object Action Expander */
- animchannelTypeInfo[type++] = &ACF_FILLDRIVERS; /* Drivers Expander */
+ animchannelTypeInfo[type++] = &ACF_FILLACTD; /* Object Action Expander */
+ animchannelTypeInfo[type++] = &ACF_FILLDRIVERS; /* Drivers Expander */
- animchannelTypeInfo[type++] = &ACF_DSMAT; /* Material Channel */
- animchannelTypeInfo[type++] = &ACF_DSLIGHT; /* Light Channel */
- animchannelTypeInfo[type++] = &ACF_DSCAM; /* Camera Channel */
- animchannelTypeInfo[type++] = &ACF_DSCACHEFILE; /* CacheFile Channel */
- animchannelTypeInfo[type++] = &ACF_DSCUR; /* Curve Channel */
- animchannelTypeInfo[type++] = &ACF_DSSKEY; /* ShapeKey Channel */
- animchannelTypeInfo[type++] = &ACF_DSWOR; /* World Channel */
- animchannelTypeInfo[type++] = &ACF_DSNTREE; /* NodeTree Channel */
- animchannelTypeInfo[type++] = &ACF_DSPART; /* Particle Channel */
- animchannelTypeInfo[type++] = &ACF_DSMBALL; /* MetaBall Channel */
- animchannelTypeInfo[type++] = &ACF_DSARM; /* Armature Channel */
- animchannelTypeInfo[type++] = &ACF_DSMESH; /* Mesh Channel */
- animchannelTypeInfo[type++] = &ACF_DSTEX; /* Texture Channel */
- animchannelTypeInfo[type++] = &ACF_DSLAT; /* Lattice Channel */
- animchannelTypeInfo[type++] = &ACF_DSLINESTYLE; /* LineStyle Channel */
- animchannelTypeInfo[type++] = &ACF_DSSPK; /* Speaker Channel */
- animchannelTypeInfo[type++] = &ACF_DSGPENCIL; /* GreasePencil Channel */
- animchannelTypeInfo[type++] = &ACF_DSMCLIP; /* MovieClip Channel */
+ animchannelTypeInfo[type++] = &ACF_DSMAT; /* Material Channel */
+ animchannelTypeInfo[type++] = &ACF_DSLIGHT; /* Light Channel */
+ animchannelTypeInfo[type++] = &ACF_DSCAM; /* Camera Channel */
+ animchannelTypeInfo[type++] = &ACF_DSCACHEFILE; /* CacheFile Channel */
+ animchannelTypeInfo[type++] = &ACF_DSCUR; /* Curve Channel */
+ animchannelTypeInfo[type++] = &ACF_DSSKEY; /* ShapeKey Channel */
+ animchannelTypeInfo[type++] = &ACF_DSWOR; /* World Channel */
+ animchannelTypeInfo[type++] = &ACF_DSNTREE; /* NodeTree Channel */
+ animchannelTypeInfo[type++] = &ACF_DSPART; /* Particle Channel */
+ animchannelTypeInfo[type++] = &ACF_DSMBALL; /* MetaBall Channel */
+ animchannelTypeInfo[type++] = &ACF_DSARM; /* Armature Channel */
+ animchannelTypeInfo[type++] = &ACF_DSMESH; /* Mesh Channel */
+ animchannelTypeInfo[type++] = &ACF_DSTEX; /* Texture Channel */
+ animchannelTypeInfo[type++] = &ACF_DSLAT; /* Lattice Channel */
+ animchannelTypeInfo[type++] = &ACF_DSLINESTYLE; /* LineStyle Channel */
+ animchannelTypeInfo[type++] = &ACF_DSSPK; /* Speaker Channel */
+ animchannelTypeInfo[type++] = &ACF_DSGPENCIL; /* GreasePencil Channel */
+ animchannelTypeInfo[type++] = &ACF_DSMCLIP; /* MovieClip Channel */
- animchannelTypeInfo[type++] = &ACF_SHAPEKEY; /* ShapeKey */
+ animchannelTypeInfo[type++] = &ACF_SHAPEKEY; /* ShapeKey */
- animchannelTypeInfo[type++] = &ACF_GPD; /* Grease Pencil Datablock */
- animchannelTypeInfo[type++] = &ACF_GPL; /* Grease Pencil Layer */
+ animchannelTypeInfo[type++] = &ACF_GPD; /* Grease Pencil Datablock */
+ animchannelTypeInfo[type++] = &ACF_GPL; /* Grease Pencil Layer */
- animchannelTypeInfo[type++] = &ACF_MASKDATA; /* Mask Datablock */
- animchannelTypeInfo[type++] = &ACF_MASKLAYER; /* Mask Layer */
+ animchannelTypeInfo[type++] = &ACF_MASKDATA; /* Mask Datablock */
+ animchannelTypeInfo[type++] = &ACF_MASKLAYER; /* Mask Layer */
- animchannelTypeInfo[type++] = &ACF_NLATRACK; /* NLA Track */
- animchannelTypeInfo[type++] = &ACF_NLAACTION; /* NLA Action */
- }
+ animchannelTypeInfo[type++] = &ACF_NLATRACK; /* NLA Track */
+ animchannelTypeInfo[type++] = &ACF_NLAACTION; /* NLA Action */
+ }
}
/* Get type info from given channel type */
const bAnimChannelType *ANIM_channel_get_typeinfo(bAnimListElem *ale)
{
- /* santiy checks */
- if (ale == NULL)
- return NULL;
+ /* santiy checks */
+ if (ale == NULL)
+ return NULL;
- /* init the typeinfo if not available yet... */
- ANIM_init_channel_typeinfo_data();
+ /* init the typeinfo if not available yet... */
+ ANIM_init_channel_typeinfo_data();
- /* check if type is in bounds... */
- if ((ale->type >= 0) && (ale->type < ANIMTYPE_NUM_TYPES))
- return animchannelTypeInfo[ale->type];
- else
- return NULL;
+ /* check if type is in bounds... */
+ if ((ale->type >= 0) && (ale->type < ANIMTYPE_NUM_TYPES))
+ return animchannelTypeInfo[ale->type];
+ else
+ return NULL;
}
/* --------------------------- */
@@ -3650,29 +3770,29 @@ const bAnimChannelType *ANIM_channel_get_typeinfo(bAnimListElem *ale)
/* Print debug info string for the given channel */
void ANIM_channel_debug_print_info(bAnimListElem *ale, short indent_level)
{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- /* print indents */
- for (; indent_level > 0; indent_level--)
- printf(" ");
+ /* print indents */
+ for (; indent_level > 0; indent_level--)
+ printf(" ");
- /* print info */
- if (acf) {
- char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
+ /* print info */
+ if (acf) {
+ char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
- /* get UI name */
- if (acf->name)
- acf->name(ale, name);
- else
- BLI_strncpy(name, "<No name>", sizeof(name));
+ /* get UI name */
+ if (acf->name)
+ acf->name(ale, name);
+ else
+ BLI_strncpy(name, "<No name>", sizeof(name));
- /* print type name + ui name */
- printf("ChanType: <%s> Name: \"%s\"\n", acf->channel_type_name, name);
- }
- else if (ale)
- printf("ChanType: <Unknown - %d>\n", ale->type);
- else
- printf("<Invalid channel - NULL>\n");
+ /* print type name + ui name */
+ printf("ChanType: <%s> Name: \"%s\"\n", acf->channel_type_name, name);
+ }
+ else if (ale)
+ printf("ChanType: <Unknown - %d>\n", ale->type);
+ else
+ printf("<Invalid channel - NULL>\n");
}
/* --------------------------- */
@@ -3682,361 +3802,374 @@ void ANIM_channel_debug_print_info(bAnimListElem *ale, short indent_level)
*/
short ANIM_channel_setting_get(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting)
{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
-
- /* 1) check that the setting exists for the current context */
- if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) {
- /* 2) get pointer to check for flag in, and the flag to check for */
- short ptrsize;
- bool negflag;
- int flag;
- void *ptr;
-
- flag = acf->setting_flag(ac, setting, &negflag);
- ptr = acf->setting_ptr(ale, setting, &ptrsize);
-
- /* check if flag is enabled */
- if (ptr && flag) {
- switch (ptrsize) {
- case sizeof(int): /* integer pointer for setting */
- {
- const int *val = (int *)ptr;
-
- if (negflag)
- return ((*val) & flag) == 0;
- else
- return ((*val) & flag) != 0;
- }
- case sizeof(short): /* short pointer for setting */
- {
- const short *val = (short *)ptr;
-
- if (negflag)
- return ((*val) & flag) == 0;
- else
- return ((*val) & flag) != 0;
- }
- case sizeof(char): /* char pointer for setting */
- {
- const char *val = (char *)ptr;
-
- if (negflag)
- return ((*val) & flag) == 0;
- else
- return ((*val) & flag) != 0;
- }
- }
- }
- }
-
- /* not found... */
- return -1;
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+
+ /* 1) check that the setting exists for the current context */
+ if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) {
+ /* 2) get pointer to check for flag in, and the flag to check for */
+ short ptrsize;
+ bool negflag;
+ int flag;
+ void *ptr;
+
+ flag = acf->setting_flag(ac, setting, &negflag);
+ ptr = acf->setting_ptr(ale, setting, &ptrsize);
+
+ /* check if flag is enabled */
+ if (ptr && flag) {
+ switch (ptrsize) {
+ case sizeof(int): /* integer pointer for setting */
+ {
+ const int *val = (int *)ptr;
+
+ if (negflag)
+ return ((*val) & flag) == 0;
+ else
+ return ((*val) & flag) != 0;
+ }
+ case sizeof(short): /* short pointer for setting */
+ {
+ const short *val = (short *)ptr;
+
+ if (negflag)
+ return ((*val) & flag) == 0;
+ else
+ return ((*val) & flag) != 0;
+ }
+ case sizeof(char): /* char pointer for setting */
+ {
+ const char *val = (char *)ptr;
+
+ if (negflag)
+ return ((*val) & flag) == 0;
+ else
+ return ((*val) & flag) != 0;
+ }
+ }
+ }
+ }
+
+ /* not found... */
+ return -1;
}
-
/* quick macro for use in ANIM_channel_setting_set - set flag for setting according the mode given */
#define ACF_SETTING_SET(sval, sflag, smode) \
- { \
- if (negflag) { \
- if (smode == ACHANNEL_SETFLAG_INVERT) (sval) ^= (sflag); \
- else if (smode == ACHANNEL_SETFLAG_ADD) (sval) &= ~(sflag); \
- else (sval) |= (sflag); \
- } \
- else { \
- if (smode == ACHANNEL_SETFLAG_INVERT) (sval) ^= (sflag); \
- else if (smode == ACHANNEL_SETFLAG_ADD) (sval) |= (sflag); \
- else (sval) &= ~(sflag); \
- } \
- } (void)0
+ { \
+ if (negflag) { \
+ if (smode == ACHANNEL_SETFLAG_INVERT) \
+ (sval) ^= (sflag); \
+ else if (smode == ACHANNEL_SETFLAG_ADD) \
+ (sval) &= ~(sflag); \
+ else \
+ (sval) |= (sflag); \
+ } \
+ else { \
+ if (smode == ACHANNEL_SETFLAG_INVERT) \
+ (sval) ^= (sflag); \
+ else if (smode == ACHANNEL_SETFLAG_ADD) \
+ (sval) |= (sflag); \
+ else \
+ (sval) &= ~(sflag); \
+ } \
+ } \
+ (void)0
/* Change value of some setting for a channel
* - setting: eAnimChannel_Settings
* - mode: eAnimChannels_SetFlag
*/
-void ANIM_channel_setting_set(bAnimContext *ac, bAnimListElem *ale, eAnimChannel_Settings setting, eAnimChannels_SetFlag mode)
-{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
-
- /* 1) check that the setting exists for the current context */
- if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) {
- /* 2) get pointer to check for flag in, and the flag to check for */
- short ptrsize;
- bool negflag;
- int flag;
- void *ptr;
-
- flag = acf->setting_flag(ac, setting, &negflag);
- ptr = acf->setting_ptr(ale, setting, &ptrsize);
-
- /* check if flag is enabled */
- if (ptr && flag) {
- switch (ptrsize) {
- case sizeof(int): /* integer pointer for setting */
- {
- int *val = (int *)ptr;
- ACF_SETTING_SET(*val, flag, mode);
- break;
- }
- case sizeof(short): /* short pointer for setting */
- {
- short *val = (short *)ptr;
- ACF_SETTING_SET(*val, flag, mode);
- break;
- }
- case sizeof(char): /* char pointer for setting */
- {
- char *val = (char *)ptr;
- ACF_SETTING_SET(*val, flag, mode);
- break;
- }
- }
- }
- }
+void ANIM_channel_setting_set(bAnimContext *ac,
+ bAnimListElem *ale,
+ eAnimChannel_Settings setting,
+ eAnimChannels_SetFlag mode)
+{
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+
+ /* 1) check that the setting exists for the current context */
+ if ((acf) && (!acf->has_setting || acf->has_setting(ac, ale, setting))) {
+ /* 2) get pointer to check for flag in, and the flag to check for */
+ short ptrsize;
+ bool negflag;
+ int flag;
+ void *ptr;
+
+ flag = acf->setting_flag(ac, setting, &negflag);
+ ptr = acf->setting_ptr(ale, setting, &ptrsize);
+
+ /* check if flag is enabled */
+ if (ptr && flag) {
+ switch (ptrsize) {
+ case sizeof(int): /* integer pointer for setting */
+ {
+ int *val = (int *)ptr;
+ ACF_SETTING_SET(*val, flag, mode);
+ break;
+ }
+ case sizeof(short): /* short pointer for setting */
+ {
+ short *val = (short *)ptr;
+ ACF_SETTING_SET(*val, flag, mode);
+ break;
+ }
+ case sizeof(char): /* char pointer for setting */
+ {
+ char *val = (char *)ptr;
+ ACF_SETTING_SET(*val, flag, mode);
+ break;
+ }
+ }
+ }
+ }
}
/* --------------------------- */
// size of icons
-#define ICON_WIDTH (0.85f * U.widget_unit)
+#define ICON_WIDTH (0.85f * U.widget_unit)
// width of sliders
-#define SLIDER_WIDTH (4 * U.widget_unit)
+#define SLIDER_WIDTH (4 * U.widget_unit)
// min-width of rename textboxes
#define RENAME_TEXT_MIN_WIDTH (U.widget_unit)
-
/* Helper - Check if a channel needs renaming */
-static bool achannel_is_being_renamed(const bAnimContext *ac, const bAnimChannelType *acf, size_t channel_index)
+static bool achannel_is_being_renamed(const bAnimContext *ac,
+ const bAnimChannelType *acf,
+ size_t channel_index)
{
- if (acf->name_prop && ac->ads) {
- /* if rename index matches, this channel is being renamed */
- if (ac->ads->renameIndex == channel_index + 1) {
- return true;
- }
- }
+ if (acf->name_prop && ac->ads) {
+ /* if rename index matches, this channel is being renamed */
+ if (ac->ads->renameIndex == channel_index + 1) {
+ return true;
+ }
+ }
- /* not being renamed */
- return false;
+ /* not being renamed */
+ return false;
}
-
/* Draw the given channel */
-void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc, size_t channel_index)
-{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- View2D *v2d = &ac->ar->v2d;
- short selected, offset;
- float y, ymid, ytext;
-
- /* sanity checks - don't draw anything */
- if (ELEM(NULL, acf, ale))
- return;
-
- /* get initial offset */
- if (acf->get_offset)
- offset = acf->get_offset(ac, ale);
- else
- offset = 0;
-
- /* calculate appropriate y-coordinates for icon buttons */
- y = (ymaxc - yminc) / 2 + yminc;
- ymid = y - 0.5f * ICON_WIDTH;
- /* y-coordinates for text is only 4 down from middle */
- ytext = y - 0.2f * U.widget_unit;
-
- /* check if channel is selected */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT))
- selected = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT);
- else
- selected = 0;
-
- /* set blending again, as may not be set in previous step */
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
-
- /* step 1) draw backdrop ........................................... */
- if (acf->draw_backdrop)
- acf->draw_backdrop(ac, ale, yminc, ymaxc);
-
- /* step 2) draw expand widget ....................................... */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
- /* just skip - drawn as widget now */
- offset += ICON_WIDTH;
- }
-
- /* step 3) draw icon ............................................... */
- if (acf->icon) {
- UI_icon_draw(offset, ymid, acf->icon(ale));
- offset += ICON_WIDTH;
- }
-
- /* turn off blending, since not needed anymore... */
- GPU_blend(false);
-
- /* step 4) draw special toggles .................................
- * - in Graph Editor, checkboxes for visibility in curves area
- * - in NLA Editor, glowing dots for solo/not solo...
- * - in Grease Pencil mode, color swatches for layer color
- */
- if (ac->sl) {
- if ((ac->spacetype == SPACE_GRAPH) &&
- (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE) ||
- acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE)))
- {
- /* for F-Curves, draw color-preview of curve behind checkbox */
- if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
- FCurve *fcu = (FCurve *)ale->data;
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- /* F-Curve channels need to have a special 'color code' box drawn, which is colored with whatever
- * color the curve has stored
- */
- immUniformColor3fv(fcu->color);
-
- /* just a solid color rect
- */
- immRectf(pos, offset, yminc, offset + ICON_WIDTH, ymaxc);
-
- immUnbindProgram();
- }
- /* icon is drawn as widget now... */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
- offset += ICON_WIDTH;
- }
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE)) {
- offset += ICON_WIDTH;
- }
- }
- else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) {
- /* just skip - drawn as widget now */
- offset += ICON_WIDTH;
- }
- else if (ale->type == ANIMTYPE_GPLAYER) {
- /* just skip - drawn as a widget */
- offset += ICON_WIDTH;
- }
- }
-
- /* step 5) draw name ............................................... */
- /* Don't draw this if renaming... */
- if (acf->name && !achannel_is_being_renamed(ac, acf, channel_index)) {
- const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
- unsigned char col[4];
-
- /* set text color */
- /* XXX: if active, highlight differently? */
-
- if (selected)
- UI_GetThemeColor4ubv(TH_TEXT_HI, col);
- else
- UI_GetThemeColor4ubv(TH_TEXT, col);
-
- /* get name */
- acf->name(ale, name);
-
- offset += 3;
- UI_fontstyle_draw_simple(fstyle, offset, ytext, name, col);
-
- /* draw red underline if channel is disabled */
- if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE) && (ale->flag & FCURVE_DISABLED)) {
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- /* FIXME: replace hardcoded color here, and check on extents! */
- immUniformColor3f(1.0f, 0.0f, 0.0f);
-
- GPU_line_width(2.0f);
-
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, (float)offset, yminc);
- immVertex2f(pos, (float)v2d->cur.xmax, yminc);
- immEnd();
-
- immUnbindProgram();
- }
- }
-
- /* step 6) draw backdrops behind mute+protection toggles + (sliders) ....................... */
- /* reset offset - now goes from RHS of panel */
- offset = 0;
-
- /* TODO: when drawing sliders, make those draw instead of these toggles if not enough space */
-
- if (v2d) {
- short draw_sliders = 0;
- float ymin_ofs = 0.0f;
- float color[3];
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- /* get and set backdrop color */
- acf->get_backdrop_color(ac, ale, color);
- immUniformColor3fv(color);
-
- /* check if we need to show the sliders */
- if ((ac->sl) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_GRAPH)) {
- switch (ac->spacetype) {
- case SPACE_ACTION:
- {
- SpaceAction *saction = (SpaceAction *)ac->sl;
- draw_sliders = (saction->flag & SACTION_SLIDERS);
- break;
- }
- case SPACE_GRAPH:
- {
- SpaceGraph *sipo = (SpaceGraph *)ac->sl;
- draw_sliders = (sipo->flag & SIPO_SLIDERS);
- break;
- }
- }
- }
-
- /* check if there's enough space for the toggles if the sliders are drawn too */
- if (!(draw_sliders) || (BLI_rcti_size_x(&v2d->mask) > ACHANNEL_BUTTON_WIDTH / 2) ) {
- /* protect... */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT))
- offset += ICON_WIDTH;
-
- /* mute... */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE))
- offset += ICON_WIDTH;
- if (ale->type == ANIMTYPE_GPLAYER)
- offset += ICON_WIDTH;
-
- /* pinned... */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PINNED))
- offset += ICON_WIDTH;
-
- /* NOTE: technically, NLA Action "pushdown" should be here too, but there are no sliders there */
-
- /* NLA action channels have slightly different spacing requirements... */
- if (ale->type == ANIMTYPE_NLAACTION)
- ymin_ofs = NLACHANNEL_SKIP;
- }
-
- /* draw slider
- * - even if we can draw sliders for this view, we must also check that the channel-type supports them
- * (only only F-Curves really can support them for now)
- * - 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)) {
- /* adjust offset */
- offset += SLIDER_WIDTH;
- }
-
-
- /* finally draw a backdrop rect behind these
- * - starts from the point where the first toggle/slider starts,
- * - ends past the space that might be reserved for a scroller
- */
- immRectf(pos, v2d->cur.xmax - (float)offset, yminc + ymin_ofs, v2d->cur.xmax + EXTRA_SCROLL_PAD, ymaxc);
-
- immUnbindProgram();
- }
+void ANIM_channel_draw(
+ bAnimContext *ac, bAnimListElem *ale, float yminc, float ymaxc, size_t channel_index)
+{
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ View2D *v2d = &ac->ar->v2d;
+ short selected, offset;
+ float y, ymid, ytext;
+
+ /* sanity checks - don't draw anything */
+ if (ELEM(NULL, acf, ale))
+ return;
+
+ /* get initial offset */
+ if (acf->get_offset)
+ offset = acf->get_offset(ac, ale);
+ else
+ offset = 0;
+
+ /* calculate appropriate y-coordinates for icon buttons */
+ y = (ymaxc - yminc) / 2 + yminc;
+ ymid = y - 0.5f * ICON_WIDTH;
+ /* y-coordinates for text is only 4 down from middle */
+ ytext = y - 0.2f * U.widget_unit;
+
+ /* check if channel is selected */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT))
+ selected = ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT);
+ else
+ selected = 0;
+
+ /* set blending again, as may not be set in previous step */
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+
+ /* step 1) draw backdrop ........................................... */
+ if (acf->draw_backdrop)
+ acf->draw_backdrop(ac, ale, yminc, ymaxc);
+
+ /* step 2) draw expand widget ....................................... */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
+ /* just skip - drawn as widget now */
+ offset += ICON_WIDTH;
+ }
+
+ /* step 3) draw icon ............................................... */
+ if (acf->icon) {
+ UI_icon_draw(offset, ymid, acf->icon(ale));
+ offset += ICON_WIDTH;
+ }
+
+ /* turn off blending, since not needed anymore... */
+ GPU_blend(false);
+
+ /* step 4) draw special toggles .................................
+ * - in Graph Editor, checkboxes for visibility in curves area
+ * - in NLA Editor, glowing dots for solo/not solo...
+ * - in Grease Pencil mode, color swatches for layer color
+ */
+ if (ac->sl) {
+ if ((ac->spacetype == SPACE_GRAPH) &&
+ (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE) ||
+ acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE))) {
+ /* for F-Curves, draw color-preview of curve behind checkbox */
+ if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
+ FCurve *fcu = (FCurve *)ale->data;
+ uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* F-Curve channels need to have a special 'color code' box drawn, which is colored with whatever
+ * color the curve has stored
+ */
+ immUniformColor3fv(fcu->color);
+
+ /* just a solid color rect
+ */
+ immRectf(pos, offset, yminc, offset + ICON_WIDTH, ymaxc);
+
+ immUnbindProgram();
+ }
+ /* icon is drawn as widget now... */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
+ offset += ICON_WIDTH;
+ }
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE)) {
+ offset += ICON_WIDTH;
+ }
+ }
+ else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) {
+ /* just skip - drawn as widget now */
+ offset += ICON_WIDTH;
+ }
+ else if (ale->type == ANIMTYPE_GPLAYER) {
+ /* just skip - drawn as a widget */
+ offset += ICON_WIDTH;
+ }
+ }
+
+ /* step 5) draw name ............................................... */
+ /* Don't draw this if renaming... */
+ if (acf->name && !achannel_is_being_renamed(ac, acf, channel_index)) {
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ char name[ANIM_CHAN_NAME_SIZE]; /* hopefully this will be enough! */
+ unsigned char col[4];
+
+ /* set text color */
+ /* XXX: if active, highlight differently? */
+
+ if (selected)
+ UI_GetThemeColor4ubv(TH_TEXT_HI, col);
+ else
+ UI_GetThemeColor4ubv(TH_TEXT, col);
+
+ /* get name */
+ acf->name(ale, name);
+
+ offset += 3;
+ UI_fontstyle_draw_simple(fstyle, offset, ytext, name, col);
+
+ /* draw red underline if channel is disabled */
+ if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE) && (ale->flag & FCURVE_DISABLED)) {
+ uint pos = GPU_vertformat_attr_add(
+ immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* FIXME: replace hardcoded color here, and check on extents! */
+ immUniformColor3f(1.0f, 0.0f, 0.0f);
+
+ GPU_line_width(2.0f);
+
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, (float)offset, yminc);
+ immVertex2f(pos, (float)v2d->cur.xmax, yminc);
+ immEnd();
+
+ immUnbindProgram();
+ }
+ }
+
+ /* step 6) draw backdrops behind mute+protection toggles + (sliders) ....................... */
+ /* reset offset - now goes from RHS of panel */
+ offset = 0;
+
+ /* TODO: when drawing sliders, make those draw instead of these toggles if not enough space */
+
+ if (v2d) {
+ short draw_sliders = 0;
+ float ymin_ofs = 0.0f;
+ float color[3];
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ /* get and set backdrop color */
+ acf->get_backdrop_color(ac, ale, color);
+ immUniformColor3fv(color);
+
+ /* check if we need to show the sliders */
+ if ((ac->sl) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_GRAPH)) {
+ switch (ac->spacetype) {
+ case SPACE_ACTION: {
+ SpaceAction *saction = (SpaceAction *)ac->sl;
+ draw_sliders = (saction->flag & SACTION_SLIDERS);
+ break;
+ }
+ case SPACE_GRAPH: {
+ SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ draw_sliders = (sipo->flag & SIPO_SLIDERS);
+ break;
+ }
+ }
+ }
+
+ /* check if there's enough space for the toggles if the sliders are drawn too */
+ if (!(draw_sliders) || (BLI_rcti_size_x(&v2d->mask) > ACHANNEL_BUTTON_WIDTH / 2)) {
+ /* protect... */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT))
+ offset += ICON_WIDTH;
+
+ /* mute... */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE))
+ offset += ICON_WIDTH;
+ if (ale->type == ANIMTYPE_GPLAYER)
+ offset += ICON_WIDTH;
+
+ /* pinned... */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PINNED))
+ offset += ICON_WIDTH;
+
+ /* NOTE: technically, NLA Action "pushdown" should be here too, but there are no sliders there */
+
+ /* NLA action channels have slightly different spacing requirements... */
+ if (ale->type == ANIMTYPE_NLAACTION)
+ ymin_ofs = NLACHANNEL_SKIP;
+ }
+
+ /* draw slider
+ * - even if we can draw sliders for this view, we must also check that the channel-type supports them
+ * (only only F-Curves really can support them for now)
+ * - 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)) {
+ /* adjust offset */
+ offset += SLIDER_WIDTH;
+ }
+
+ /* finally draw a backdrop rect behind these
+ * - starts from the point where the first toggle/slider starts,
+ * - ends past the space that might be reserved for a scroller
+ */
+ immRectf(pos,
+ v2d->cur.xmax - (float)offset,
+ yminc + ymin_ofs,
+ v2d->cur.xmax + EXTRA_SCROLL_PAD,
+ ymaxc);
+
+ immUnbindProgram();
+ }
}
/* ------------------ */
@@ -4044,711 +4177,803 @@ void ANIM_channel_draw(bAnimContext *ac, bAnimListElem *ale, float yminc, float
/* callback for (normal) widget settings - send notifiers */
static void achannel_setting_widget_cb(bContext *C, void *UNUSED(arg1), void *UNUSED(arg2))
{
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
}
/* callback for widget settings that need flushing */
static void achannel_setting_flush_widget_cb(bContext *C, void *ale_npoin, void *setting_wrap)
{
- bAnimListElem *ale_setting = (bAnimListElem *)ale_npoin;
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- int filter;
- int setting = POINTER_AS_INT(setting_wrap);
- short on = 0;
+ bAnimListElem *ale_setting = (bAnimListElem *)ale_npoin;
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ int filter;
+ int setting = POINTER_AS_INT(setting_wrap);
+ short on = 0;
- /* send notifiers before doing anything else... */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* send notifiers before doing anything else... */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- /* verify that we have a channel to operate on. */
- if (!ale_setting) {
- return;
- }
+ /* verify that we have a channel to operate on. */
+ if (!ale_setting) {
+ return;
+ }
- if (ale_setting->type == ANIMTYPE_GPLAYER) {
- /* draw cache updates for settings that affect the visible strokes */
- if (setting == ACHANNEL_SETTING_VISIBLE) {
- bGPdata *gpd = (bGPdata *)ale_setting->id;
- DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
- }
+ if (ale_setting->type == ANIMTYPE_GPLAYER) {
+ /* draw cache updates for settings that affect the visible strokes */
+ if (setting == ACHANNEL_SETTING_VISIBLE) {
+ bGPdata *gpd = (bGPdata *)ale_setting->id;
+ DEG_id_tag_update(&gpd->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ }
- /* UI updates */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL);
- }
+ /* UI updates */
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA, NULL);
+ }
- /* Tag for full animation update, so that the settings will have an effect. */
- if (ale_setting->id) {
- DEG_id_tag_update(ale_setting->id, ID_RECALC_ANIMATION);
- }
- if (ale_setting->adt && ale_setting->adt->action) {
- /* Action is it's own datablock, so has to be tagged specifically. */
- DEG_id_tag_update(&ale_setting->adt->action->id, ID_RECALC_ANIMATION);
- }
+ /* Tag for full animation update, so that the settings will have an effect. */
+ if (ale_setting->id) {
+ DEG_id_tag_update(ale_setting->id, ID_RECALC_ANIMATION);
+ }
+ if (ale_setting->adt && ale_setting->adt->action) {
+ /* Action is it's own datablock, so has to be tagged specifically. */
+ DEG_id_tag_update(&ale_setting->adt->action->id, ID_RECALC_ANIMATION);
+ }
- /* verify animation context */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return;
+ /* verify animation context */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return;
- /* check if the setting is on... */
- on = ANIM_channel_setting_get(&ac, ale_setting, setting);
+ /* check if the setting is on... */
+ on = ANIM_channel_setting_get(&ac, ale_setting, setting);
- /* on == -1 means setting not found... */
- if (on == -1) {
- return;
- }
+ /* on == -1 means setting not found... */
+ if (on == -1) {
+ return;
+ }
- /* get all channels that can possibly be chosen - but ignore hierarchy */
- filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* get all channels that can possibly be chosen - but ignore hierarchy */
+ filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- /* call API method to flush the setting */
- ANIM_flush_setting_anim_channels(&ac, &anim_data, ale_setting, setting, on);
+ /* call API method to flush the setting */
+ ANIM_flush_setting_anim_channels(&ac, &anim_data, ale_setting, setting, on);
- /* free temp data */
- ANIM_animdata_freelist(&anim_data);
+ /* free temp data */
+ ANIM_animdata_freelist(&anim_data);
}
/* callback for wrapping NLA Track "solo" toggle logic */
static void achannel_nlatrack_solo_widget_cb(bContext *C, void *ale_poin, void *UNUSED(arg2))
{
- bAnimListElem *ale = ale_poin;
- AnimData *adt = ale->adt;
- NlaTrack *nlt = ale->data;
+ bAnimListElem *ale = ale_poin;
+ AnimData *adt = ale->adt;
+ NlaTrack *nlt = ale->data;
- /* Toggle 'solo' mode. There are several complications here which need explaining:
- * - The method call is needed to perform a few additional validation operations
- * to ensure that the mode is applied properly
- * - BUT, since the button already toggles the value, we need to un-toggle it
- * before the API call gets to it, otherwise it will end up clearing the result
- * again!
- */
- nlt->flag ^= NLATRACK_SOLO;
- BKE_nlatrack_solo_toggle(adt, nlt);
+ /* Toggle 'solo' mode. There are several complications here which need explaining:
+ * - The method call is needed to perform a few additional validation operations
+ * to ensure that the mode is applied properly
+ * - BUT, since the button already toggles the value, we need to un-toggle it
+ * before the API call gets to it, otherwise it will end up clearing the result
+ * again!
+ */
+ nlt->flag ^= NLATRACK_SOLO;
+ BKE_nlatrack_solo_toggle(adt, nlt);
- /* send notifiers */
- DEG_id_tag_update(ale->id, ID_RECALC_ANIMATION);
- WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
+ /* send notifiers */
+ DEG_id_tag_update(ale->id, ID_RECALC_ANIMATION);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_NLA | NA_EDITED, NULL);
}
/* callback for widget sliders - insert keyframes */
static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poin)
{
- ID *id = (ID *)id_poin;
- AnimData *adt = BKE_animdata_from_id(id);
- FCurve *fcu = (FCurve *)fcu_poin;
+ ID *id = (ID *)id_poin;
+ AnimData *adt = BKE_animdata_from_id(id);
+ FCurve *fcu = (FCurve *)fcu_poin;
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ReportList *reports = CTX_wm_reports(C);
- Scene *scene = CTX_data_scene(C);
- ToolSettings *ts = scene->toolsettings;
- ListBase nla_cache = {NULL, NULL};
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
- short flag = 0;
- bool done = false;
- float cfra;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ReportList *reports = CTX_wm_reports(C);
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = scene->toolsettings;
+ ListBase nla_cache = {NULL, NULL};
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ short flag = 0;
+ bool done = false;
+ float cfra;
- /* Get RNA pointer */
- RNA_id_pointer_create(id, &id_ptr);
+ /* Get RNA pointer */
+ RNA_id_pointer_create(id, &id_ptr);
- /* Get NLA context for value remapping */
- NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(&nla_cache, depsgraph, &id_ptr, adt, (float)CFRA);
+ /* Get NLA context for value remapping */
+ NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
+ &nla_cache, depsgraph, &id_ptr, adt, (float)CFRA);
- /* get current frame and apply NLA-mapping to it (if applicable) */
- cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+ /* get current frame and apply NLA-mapping to it (if applicable) */
+ cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
- /* get flags for keyframing */
- flag = ANIM_get_keyframing_flags(scene, 1);
+ /* get flags for keyframing */
+ flag = ANIM_get_keyframing_flags(scene, 1);
- /* try to resolve the path stored in the F-Curve */
- if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
- /* set the special 'replace' flag if on a keyframe */
- if (fcurve_frame_has_keyframe(fcu, cfra, 0))
- flag |= INSERTKEY_REPLACE;
+ /* try to resolve the path stored in the F-Curve */
+ if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
+ /* set the special 'replace' flag if on a keyframe */
+ if (fcurve_frame_has_keyframe(fcu, cfra, 0))
+ flag |= INSERTKEY_REPLACE;
- /* insert a keyframe for this F-Curve */
- done = insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, nla_context, flag);
+ /* insert a keyframe for this F-Curve */
+ done = insert_keyframe_direct(
+ depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, nla_context, flag);
- if (done) {
- if (adt->action != NULL) {
- DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
- }
- DEG_id_tag_update(id, ID_RECALC_ANIMATION_NO_FLUSH);
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- }
- }
+ if (done) {
+ if (adt->action != NULL) {
+ DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
+ }
+ DEG_id_tag_update(id, ID_RECALC_ANIMATION_NO_FLUSH);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ }
+ }
- BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
+ BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
}
/* callback for shapekey widget sliders - insert keyframes */
static void achannel_setting_slider_shapekey_cb(bContext *C, void *key_poin, void *kb_poin)
{
- Main *bmain = CTX_data_main(C);
- Key *key = (Key *)key_poin;
- KeyBlock *kb = (KeyBlock *)kb_poin;
- char *rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
+ Main *bmain = CTX_data_main(C);
+ Key *key = (Key *)key_poin;
+ KeyBlock *kb = (KeyBlock *)kb_poin;
+ char *rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ReportList *reports = CTX_wm_reports(C);
- Scene *scene = CTX_data_scene(C);
- ToolSettings *ts = scene->toolsettings;
- ListBase nla_cache = {NULL, NULL};
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
- short flag = 0;
- bool done = false;
- float cfra;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ReportList *reports = CTX_wm_reports(C);
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = scene->toolsettings;
+ ListBase nla_cache = {NULL, NULL};
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ short flag = 0;
+ bool done = false;
+ float cfra;
- /* Get RNA pointer */
- RNA_id_pointer_create((ID *)key, &id_ptr);
+ /* Get RNA pointer */
+ RNA_id_pointer_create((ID *)key, &id_ptr);
- /* Get NLA context for value remapping */
- NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(&nla_cache, depsgraph, &id_ptr, key->adt, (float)CFRA);
+ /* Get NLA context for value remapping */
+ NlaKeyframingContext *nla_context = BKE_animsys_get_nla_keyframing_context(
+ &nla_cache, depsgraph, &id_ptr, key->adt, (float)CFRA);
- /* get current frame and apply NLA-mapping to it (if applicable) */
- cfra = BKE_nla_tweakedit_remap(key->adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+ /* get current frame and apply NLA-mapping to it (if applicable) */
+ cfra = BKE_nla_tweakedit_remap(key->adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
- /* get flags for keyframing */
- flag = ANIM_get_keyframing_flags(scene, 1);
+ /* get flags for keyframing */
+ flag = ANIM_get_keyframing_flags(scene, 1);
- /* try to resolve the path stored in the F-Curve */
- if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop)) {
- /* find or create new F-Curve */
- // XXX is the group name for this ok?
- bAction *act = verify_adt_action(bmain, (ID *)key, 1);
- FCurve *fcu = verify_fcurve(bmain, act, NULL, &ptr, rna_path, 0, 1);
+ /* try to resolve the path stored in the F-Curve */
+ if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop)) {
+ /* find or create new F-Curve */
+ // XXX is the group name for this ok?
+ bAction *act = verify_adt_action(bmain, (ID *)key, 1);
+ FCurve *fcu = verify_fcurve(bmain, act, NULL, &ptr, rna_path, 0, 1);
- /* set the special 'replace' flag if on a keyframe */
- if (fcurve_frame_has_keyframe(fcu, cfra, 0))
- flag |= INSERTKEY_REPLACE;
+ /* set the special 'replace' flag if on a keyframe */
+ if (fcurve_frame_has_keyframe(fcu, cfra, 0))
+ flag |= INSERTKEY_REPLACE;
- /* insert a keyframe for this F-Curve */
- done = insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, nla_context, flag);
+ /* insert a keyframe for this F-Curve */
+ done = insert_keyframe_direct(
+ depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, nla_context, flag);
- if (done)
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- }
+ if (done)
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ }
- /* free the path */
- if (rna_path)
- MEM_freeN(rna_path);
+ /* free the path */
+ if (rna_path)
+ MEM_freeN(rna_path);
- BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
+ BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
}
/* callback for NLA Control Curve widget sliders - insert keyframes */
-static void achannel_setting_slider_nla_curve_cb(bContext *C, void *UNUSED(id_poin), void *fcu_poin)
+static void achannel_setting_slider_nla_curve_cb(bContext *C,
+ void *UNUSED(id_poin),
+ void *fcu_poin)
{
- /* ID *id = (ID *)id_poin; */
- FCurve *fcu = (FCurve *)fcu_poin;
+ /* ID *id = (ID *)id_poin; */
+ FCurve *fcu = (FCurve *)fcu_poin;
- PointerRNA ptr;
- PropertyRNA *prop;
- int index;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- ReportList *reports = CTX_wm_reports(C);
- Scene *scene = CTX_data_scene(C);
- ToolSettings *ts = scene->toolsettings;
- short flag = 0;
- bool done = false;
- float cfra;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ ReportList *reports = CTX_wm_reports(C);
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = scene->toolsettings;
+ short flag = 0;
+ bool done = false;
+ float cfra;
- /* get current frame - *no* NLA mapping should be done */
- cfra = (float)CFRA;
+ /* get current frame - *no* NLA mapping should be done */
+ cfra = (float)CFRA;
- /* get flags for keyframing */
- flag = ANIM_get_keyframing_flags(scene, 1);
+ /* get flags for keyframing */
+ flag = ANIM_get_keyframing_flags(scene, 1);
- /* get pointer and property from the slider - this should all match up with the NlaStrip required... */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ /* get pointer and property from the slider - this should all match up with the NlaStrip required... */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- if (fcu && prop) {
- /* set the special 'replace' flag if on a keyframe */
- if (fcurve_frame_has_keyframe(fcu, cfra, 0))
- flag |= INSERTKEY_REPLACE;
+ if (fcu && prop) {
+ /* set the special 'replace' flag if on a keyframe */
+ if (fcurve_frame_has_keyframe(fcu, cfra, 0))
+ flag |= INSERTKEY_REPLACE;
- /* insert a keyframe for this F-Curve */
- done = insert_keyframe_direct(depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, flag);
+ /* insert a keyframe for this F-Curve */
+ done = insert_keyframe_direct(
+ depsgraph, reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, flag);
- if (done)
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- }
+ if (done)
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ }
}
/* Draw a widget for some setting */
-static void draw_setting_widget(bAnimContext *ac, bAnimListElem *ale, const bAnimChannelType *acf,
- uiBlock *block, int xpos, int ypos, int setting)
-{
- short ptrsize, butType;
- bool negflag;
- bool usetoggle = true;
- int flag, icon;
- void *ptr;
- const char *tooltip;
- uiBut *but = NULL;
- bool enabled;
-
- /* get the flag and the pointer to that flag */
- flag = acf->setting_flag(ac, setting, &negflag);
- ptr = acf->setting_ptr(ale, setting, &ptrsize);
- enabled = ANIM_channel_setting_get(ac, ale, setting);
-
- /* get the base icon for the setting */
- switch (setting) {
- case ACHANNEL_SETTING_VISIBLE: /* visibility eyes */
- //icon = ((enabled) ? ICON_VISIBLE_IPO_ON : ICON_VISIBLE_IPO_OFF);
- icon = ICON_VISIBLE_IPO_OFF;
-
- if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE))
- tooltip = TIP_("F-Curve is visible in Graph Editor for editing");
- else if (ale->type == ANIMTYPE_GPLAYER)
- tooltip = TIP_("Grease Pencil layer is visible in the viewport");
- else
- tooltip = TIP_("Channels are visible in Graph Editor for editing");
- break;
-
- case ACHANNEL_SETTING_ALWAYS_VISIBLE:
- icon = ICON_UNPINNED;
- tooltip = TIP_("Channels are visible in Graph Editor for editing");
- break;
-
- case ACHANNEL_SETTING_MOD_OFF: /* modifiers disabled */
- icon = ICON_MODIFIER_OFF;
- tooltip = TIP_("F-Curve modifiers are disabled");
- break;
-
- case ACHANNEL_SETTING_EXPAND: /* expanded triangle */
- //icon = ((enabled) ? ICON_TRIA_DOWN : ICON_TRIA_RIGHT);
- icon = ICON_TRIA_RIGHT;
- tooltip = TIP_("Make channels grouped under this channel visible");
- break;
-
- case ACHANNEL_SETTING_SOLO: /* NLA Tracks only */
- //icon = ((enabled) ? ICON_SOLO_OFF : ICON_SOLO_ON);
- icon = ICON_SOLO_OFF;
- tooltip = TIP_("NLA Track is the only one evaluated in this animation data-block, with all others muted");
- break;
-
- /* --- */
-
- case ACHANNEL_SETTING_PROTECT: /* protected lock */
- // TODO: what about when there's no protect needed?
- //icon = ((enabled) ? ICON_LOCKED : ICON_UNLOCKED);
- icon = ICON_UNLOCKED;
-
- if (ale->datatype != ALE_NLASTRIP)
- tooltip = TIP_("Editability of keyframes for this channel");
- else
- tooltip = TIP_("Editability of NLA Strips in this track");
- break;
-
- case ACHANNEL_SETTING_MUTE: /* muted speaker */
- icon = ((enabled) ? ICON_CHECKBOX_DEHLT : ICON_CHECKBOX_HLT);
- usetoggle = false;
-
- if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
- tooltip = TIP_("Does F-Curve contribute to result");
- }
- else if ((ac) && (ac->spacetype == SPACE_NLA) && (ale->type != ANIMTYPE_NLATRACK)) {
- tooltip = TIP_("Temporarily disable NLA stack evaluation (i.e. only the active action is evaluated)");
- }
- else if (ale->type == ANIMTYPE_GPLAYER) {
- tooltip = TIP_("Lock current frame displayed by layer (i.e. disable animation playback)");
- }
- else {
- tooltip = TIP_("Do channels contribute to result (toggle channel muting)");
- }
- break;
-
- case ACHANNEL_SETTING_PINNED: /* pin icon */
- //icon = ((enabled) ? ICON_PINNED : ICON_UNPINNED);
- icon = ICON_UNPINNED;
-
- if (ale->type == ANIMTYPE_NLAACTION) {
- tooltip = TIP_("Display action without any time remapping (when unpinned)");
- }
- else {
- /* TODO: there are no other tools which require the 'pinning' concept yet */
- tooltip = NULL;
- }
- break;
-
- default:
- tooltip = NULL;
- icon = 0;
- break;
- }
-
- /* type of button */
- if (usetoggle) {
- if (negflag)
- butType = UI_BTYPE_ICON_TOGGLE_N;
- else
- butType = UI_BTYPE_ICON_TOGGLE;
- }
- else {
- if (negflag)
- butType = UI_BTYPE_TOGGLE_N;
- else
- butType = UI_BTYPE_TOGGLE;
- }
- /* draw button for setting */
- if (ptr && flag) {
- switch (ptrsize) {
- case sizeof(int): /* integer pointer for setting */
- but = uiDefIconButBitI(block, butType, flag, 0, icon,
- xpos, ypos, ICON_WIDTH, ICON_WIDTH, ptr, 0, 0, 0, 0, tooltip);
- break;
-
- case sizeof(short): /* short pointer for setting */
- but = uiDefIconButBitS(block, butType, flag, 0, icon,
- xpos, ypos, ICON_WIDTH, ICON_WIDTH, ptr, 0, 0, 0, 0, tooltip);
- break;
-
- case sizeof(char): /* char pointer for setting */
- but = uiDefIconButBitC(block, butType, flag, 0, icon,
- xpos, ypos, ICON_WIDTH, ICON_WIDTH, ptr, 0, 0, 0, 0, tooltip);
- break;
- }
-
- /* set call to send relevant notifiers and/or perform type-specific updates */
- if (but) {
- switch (setting) {
- /* settings needing flushing up/down hierarchy */
- case ACHANNEL_SETTING_VISIBLE: /* Graph Editor - 'visibility' toggles */
- case ACHANNEL_SETTING_PROTECT: /* General - protection flags */
- case ACHANNEL_SETTING_MUTE: /* General - muting flags */
- case ACHANNEL_SETTING_PINNED: /* NLA Actions - 'map/nomap' */
- case ACHANNEL_SETTING_MOD_OFF:
- case ACHANNEL_SETTING_ALWAYS_VISIBLE:
- UI_but_funcN_set(but, achannel_setting_flush_widget_cb, MEM_dupallocN(ale), POINTER_FROM_INT(setting));
- break;
-
- /* settings needing special attention */
- case ACHANNEL_SETTING_SOLO: /* NLA Tracks - Solo toggle */
- UI_but_funcN_set(but, achannel_nlatrack_solo_widget_cb, MEM_dupallocN(ale), NULL);
- break;
-
- /* no flushing */
- case ACHANNEL_SETTING_EXPAND: /* expanding - cannot flush,
- * otherwise all would open/close at once */
- default:
- UI_but_func_set(but, achannel_setting_widget_cb, NULL, NULL);
- break;
- }
- }
- }
-
- if ((ale->fcurve_owner_id != NULL && ID_IS_LINKED(ale->fcurve_owner_id)) ||
- (ale->id != NULL && ID_IS_LINKED(ale->id)))
- {
- UI_but_flag_enable(but, UI_BUT_DISABLED);
- }
+static void draw_setting_widget(bAnimContext *ac,
+ bAnimListElem *ale,
+ const bAnimChannelType *acf,
+ uiBlock *block,
+ int xpos,
+ int ypos,
+ int setting)
+{
+ short ptrsize, butType;
+ bool negflag;
+ bool usetoggle = true;
+ int flag, icon;
+ void *ptr;
+ const char *tooltip;
+ uiBut *but = NULL;
+ bool enabled;
+
+ /* get the flag and the pointer to that flag */
+ flag = acf->setting_flag(ac, setting, &negflag);
+ ptr = acf->setting_ptr(ale, setting, &ptrsize);
+ enabled = ANIM_channel_setting_get(ac, ale, setting);
+
+ /* get the base icon for the setting */
+ switch (setting) {
+ case ACHANNEL_SETTING_VISIBLE: /* visibility eyes */
+ //icon = ((enabled) ? ICON_VISIBLE_IPO_ON : ICON_VISIBLE_IPO_OFF);
+ icon = ICON_VISIBLE_IPO_OFF;
+
+ if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE))
+ tooltip = TIP_("F-Curve is visible in Graph Editor for editing");
+ else if (ale->type == ANIMTYPE_GPLAYER)
+ tooltip = TIP_("Grease Pencil layer is visible in the viewport");
+ else
+ tooltip = TIP_("Channels are visible in Graph Editor for editing");
+ break;
+
+ case ACHANNEL_SETTING_ALWAYS_VISIBLE:
+ icon = ICON_UNPINNED;
+ tooltip = TIP_("Channels are visible in Graph Editor for editing");
+ break;
+
+ case ACHANNEL_SETTING_MOD_OFF: /* modifiers disabled */
+ icon = ICON_MODIFIER_OFF;
+ tooltip = TIP_("F-Curve modifiers are disabled");
+ break;
+
+ case ACHANNEL_SETTING_EXPAND: /* expanded triangle */
+ //icon = ((enabled) ? ICON_TRIA_DOWN : ICON_TRIA_RIGHT);
+ icon = ICON_TRIA_RIGHT;
+ tooltip = TIP_("Make channels grouped under this channel visible");
+ break;
+
+ case ACHANNEL_SETTING_SOLO: /* NLA Tracks only */
+ //icon = ((enabled) ? ICON_SOLO_OFF : ICON_SOLO_ON);
+ icon = ICON_SOLO_OFF;
+ tooltip = TIP_(
+ "NLA Track is the only one evaluated in this animation data-block, with all others "
+ "muted");
+ break;
+
+ /* --- */
+
+ case ACHANNEL_SETTING_PROTECT: /* protected lock */
+ // TODO: what about when there's no protect needed?
+ //icon = ((enabled) ? ICON_LOCKED : ICON_UNLOCKED);
+ icon = ICON_UNLOCKED;
+
+ if (ale->datatype != ALE_NLASTRIP)
+ tooltip = TIP_("Editability of keyframes for this channel");
+ else
+ tooltip = TIP_("Editability of NLA Strips in this track");
+ break;
+
+ case ACHANNEL_SETTING_MUTE: /* muted speaker */
+ icon = ((enabled) ? ICON_CHECKBOX_DEHLT : ICON_CHECKBOX_HLT);
+ usetoggle = false;
+
+ if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE)) {
+ tooltip = TIP_("Does F-Curve contribute to result");
+ }
+ else if ((ac) && (ac->spacetype == SPACE_NLA) && (ale->type != ANIMTYPE_NLATRACK)) {
+ tooltip = TIP_(
+ "Temporarily disable NLA stack evaluation (i.e. only the active action is evaluated)");
+ }
+ else if (ale->type == ANIMTYPE_GPLAYER) {
+ tooltip = TIP_("Lock current frame displayed by layer (i.e. disable animation playback)");
+ }
+ else {
+ tooltip = TIP_("Do channels contribute to result (toggle channel muting)");
+ }
+ break;
+
+ case ACHANNEL_SETTING_PINNED: /* pin icon */
+ //icon = ((enabled) ? ICON_PINNED : ICON_UNPINNED);
+ icon = ICON_UNPINNED;
+
+ if (ale->type == ANIMTYPE_NLAACTION) {
+ tooltip = TIP_("Display action without any time remapping (when unpinned)");
+ }
+ else {
+ /* TODO: there are no other tools which require the 'pinning' concept yet */
+ tooltip = NULL;
+ }
+ break;
+
+ default:
+ tooltip = NULL;
+ icon = 0;
+ break;
+ }
+
+ /* type of button */
+ if (usetoggle) {
+ if (negflag)
+ butType = UI_BTYPE_ICON_TOGGLE_N;
+ else
+ butType = UI_BTYPE_ICON_TOGGLE;
+ }
+ else {
+ if (negflag)
+ butType = UI_BTYPE_TOGGLE_N;
+ else
+ butType = UI_BTYPE_TOGGLE;
+ }
+ /* draw button for setting */
+ if (ptr && flag) {
+ switch (ptrsize) {
+ case sizeof(int): /* integer pointer for setting */
+ but = uiDefIconButBitI(block,
+ butType,
+ flag,
+ 0,
+ icon,
+ xpos,
+ ypos,
+ ICON_WIDTH,
+ ICON_WIDTH,
+ ptr,
+ 0,
+ 0,
+ 0,
+ 0,
+ tooltip);
+ break;
+
+ case sizeof(short): /* short pointer for setting */
+ but = uiDefIconButBitS(block,
+ butType,
+ flag,
+ 0,
+ icon,
+ xpos,
+ ypos,
+ ICON_WIDTH,
+ ICON_WIDTH,
+ ptr,
+ 0,
+ 0,
+ 0,
+ 0,
+ tooltip);
+ break;
+
+ case sizeof(char): /* char pointer for setting */
+ but = uiDefIconButBitC(block,
+ butType,
+ flag,
+ 0,
+ icon,
+ xpos,
+ ypos,
+ ICON_WIDTH,
+ ICON_WIDTH,
+ ptr,
+ 0,
+ 0,
+ 0,
+ 0,
+ tooltip);
+ break;
+ }
+
+ /* set call to send relevant notifiers and/or perform type-specific updates */
+ if (but) {
+ switch (setting) {
+ /* settings needing flushing up/down hierarchy */
+ case ACHANNEL_SETTING_VISIBLE: /* Graph Editor - 'visibility' toggles */
+ case ACHANNEL_SETTING_PROTECT: /* General - protection flags */
+ case ACHANNEL_SETTING_MUTE: /* General - muting flags */
+ case ACHANNEL_SETTING_PINNED: /* NLA Actions - 'map/nomap' */
+ case ACHANNEL_SETTING_MOD_OFF:
+ case ACHANNEL_SETTING_ALWAYS_VISIBLE:
+ UI_but_funcN_set(but,
+ achannel_setting_flush_widget_cb,
+ MEM_dupallocN(ale),
+ POINTER_FROM_INT(setting));
+ break;
+
+ /* settings needing special attention */
+ case ACHANNEL_SETTING_SOLO: /* NLA Tracks - Solo toggle */
+ UI_but_funcN_set(but, achannel_nlatrack_solo_widget_cb, MEM_dupallocN(ale), NULL);
+ break;
+
+ /* no flushing */
+ case ACHANNEL_SETTING_EXPAND: /* expanding - cannot flush,
+ * otherwise all would open/close at once */
+ default:
+ UI_but_func_set(but, achannel_setting_widget_cb, NULL, NULL);
+ break;
+ }
+ }
+ }
+
+ if ((ale->fcurve_owner_id != NULL && ID_IS_LINKED(ale->fcurve_owner_id)) ||
+ (ale->id != NULL && ID_IS_LINKED(ale->id))) {
+ UI_but_flag_enable(but, UI_BUT_DISABLED);
+ }
}
/* Draw UI widgets the given channel */
-void ANIM_channel_draw_widgets(
- const bContext *C,
- bAnimContext *ac,
- bAnimListElem *ale,
- uiBlock *block,
- rctf *rect,
- size_t channel_index)
-{
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- View2D *v2d = &ac->ar->v2d;
- float ymid;
- const short channel_height = round_fl_to_int(BLI_rctf_size_y(rect));
- const bool is_being_renamed = achannel_is_being_renamed(ac, acf, channel_index);
-
- /* sanity checks - don't draw anything */
- if (ELEM(NULL, acf, ale, block))
- return;
-
- /* get initial offset */
- short offset = rect->xmin;
- if (acf->get_offset) {
- offset += acf->get_offset(ac, ale);
- }
-
- /* calculate appropriate y-coordinates for icon buttons */
- ymid = BLI_rctf_cent_y(rect) - 0.5f * ICON_WIDTH;
-
- /* no button backdrop behind icons */
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
- /* step 1) draw expand widget ....................................... */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
- draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_EXPAND);
- offset += ICON_WIDTH;
- }
-
- /* step 2) draw icon ............................................... */
- if (acf->icon) {
- /* icon is not drawn here (not a widget) */
- offset += ICON_WIDTH;
- }
-
- /* step 3) draw special toggles .................................
- * - in Graph Editor, checkboxes for visibility in curves area
- * - in NLA Editor, glowing dots for solo/not solo...
- * - in Grease Pencil mode, color swatches for layer color
- */
- if (ac->sl) {
- if ((ac->spacetype == SPACE_GRAPH) &&
- (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE) ||
- acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE)))
- {
- /* pin toggle */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE)) {
- draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_ALWAYS_VISIBLE);
- offset += ICON_WIDTH;
- }
- /* visibility toggle */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
- draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_VISIBLE);
- offset += ICON_WIDTH;
- }
- }
- else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) {
- /* 'solo' setting for NLA Tracks */
- draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_SOLO);
- offset += ICON_WIDTH;
- }
- else if (ale->type == ANIMTYPE_GPLAYER) {
+void ANIM_channel_draw_widgets(const bContext *C,
+ bAnimContext *ac,
+ bAnimListElem *ale,
+ uiBlock *block,
+ rctf *rect,
+ size_t channel_index)
+{
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ View2D *v2d = &ac->ar->v2d;
+ float ymid;
+ const short channel_height = round_fl_to_int(BLI_rctf_size_y(rect));
+ const bool is_being_renamed = achannel_is_being_renamed(ac, acf, channel_index);
+
+ /* sanity checks - don't draw anything */
+ if (ELEM(NULL, acf, ale, block))
+ return;
+
+ /* get initial offset */
+ short offset = rect->xmin;
+ if (acf->get_offset) {
+ offset += acf->get_offset(ac, ale);
+ }
+
+ /* calculate appropriate y-coordinates for icon buttons */
+ ymid = BLI_rctf_cent_y(rect) - 0.5f * ICON_WIDTH;
+
+ /* no button backdrop behind icons */
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+
+ /* step 1) draw expand widget ....................................... */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_EXPAND)) {
+ draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_EXPAND);
+ offset += ICON_WIDTH;
+ }
+
+ /* step 2) draw icon ............................................... */
+ if (acf->icon) {
+ /* icon is not drawn here (not a widget) */
+ offset += ICON_WIDTH;
+ }
+
+ /* step 3) draw special toggles .................................
+ * - in Graph Editor, checkboxes for visibility in curves area
+ * - in NLA Editor, glowing dots for solo/not solo...
+ * - in Grease Pencil mode, color swatches for layer color
+ */
+ if (ac->sl) {
+ if ((ac->spacetype == SPACE_GRAPH) &&
+ (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE) ||
+ acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE))) {
+ /* pin toggle */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_ALWAYS_VISIBLE)) {
+ draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_ALWAYS_VISIBLE);
+ offset += ICON_WIDTH;
+ }
+ /* visibility toggle */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_VISIBLE)) {
+ draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_VISIBLE);
+ offset += ICON_WIDTH;
+ }
+ }
+ else if ((ac->spacetype == SPACE_NLA) && acf->has_setting(ac, ale, ACHANNEL_SETTING_SOLO)) {
+ /* 'solo' setting for NLA Tracks */
+ draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_SOLO);
+ offset += ICON_WIDTH;
+ }
+ else if (ale->type == ANIMTYPE_GPLAYER) {
#if 0
- /* XXX: Maybe need a better design */
- /* color swatch for layer color */
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
- PointerRNA ptr;
- float w = ICON_WIDTH / 2.0f;
-
- RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, &ptr);
-
- UI_block_align_begin(block);
- UI_block_emboss_set(block, RNA_boolean_get(&ptr, "is_stroke_visible") ? UI_EMBOSS : UI_EMBOSS_NONE);
- uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset, yminc, w, ICON_WIDTH,
- &ptr, "color", -1,
- 0, 0, 0, 0, gpl->info);
-
- UI_block_emboss_set(block, RNA_boolean_get(&ptr, "is_fill_visible") ? UI_EMBOSS : UI_EMBOSS_NONE);
- uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset + w, yminc, w, ICON_WIDTH,
- &ptr, "fill_color", -1,
- 0, 0, 0, 0, gpl->info);
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- UI_block_align_end(block);
-
- offset += ICON_WIDTH;
+ /* XXX: Maybe need a better design */
+ /* color swatch for layer color */
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+ PointerRNA ptr;
+ float w = ICON_WIDTH / 2.0f;
+
+ RNA_pointer_create(ale->id, &RNA_GPencilLayer, ale->data, &ptr);
+
+ UI_block_align_begin(block);
+ UI_block_emboss_set(block, RNA_boolean_get(&ptr, "is_stroke_visible") ? UI_EMBOSS : UI_EMBOSS_NONE);
+ uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset, yminc, w, ICON_WIDTH,
+ &ptr, "color", -1,
+ 0, 0, 0, 0, gpl->info);
+
+ UI_block_emboss_set(block, RNA_boolean_get(&ptr, "is_fill_visible") ? UI_EMBOSS : UI_EMBOSS_NONE);
+ uiDefButR(block, UI_BTYPE_COLOR, 1, "", offset + w, yminc, w, ICON_WIDTH,
+ &ptr, "fill_color", -1,
+ 0, 0, 0, 0, gpl->info);
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ UI_block_align_end(block);
+
+ offset += ICON_WIDTH;
#endif
- }
- }
-
- /* step 4) draw text - check if renaming widget is in use... */
- if (is_being_renamed) {
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
-
- /* draw renaming widget if we can get RNA pointer for it
- * NOTE: property may only be available in some cases, even if we have
- * a callback available (e.g. broken F-Curve rename)
- */
- if (acf->name_prop(ale, &ptr, &prop)) {
- const short margin_x = 3 * round_fl_to_int(UI_DPI_FAC);
- const short width = ac->ar->winx - offset - (margin_x * 2);
- uiBut *but;
-
- UI_block_emboss_set(block, UI_EMBOSS);
-
- but = uiDefButR(block, UI_BTYPE_TEXT, 1, "", offset + margin_x, rect->ymin,
- MAX2(width, RENAME_TEXT_MIN_WIDTH), channel_height,
- &ptr, RNA_property_identifier(prop), -1, 0, 0, -1, -1, NULL);
-
- /* copy what outliner does here, see outliner_buttons */
- if (UI_but_active_only(C, ac->ar, block, but) == false) {
- ac->ads->renameIndex = 0;
-
- /* send notifiers */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL);
- }
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- }
- else {
- /* Cannot get property/cannot or rename for some reason, so clear rename index
- * so that this doesn't hang around, and the name can be drawn normally - T47492
- */
- ac->ads->renameIndex = 0;
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
- }
- }
-
- /* step 5) draw mute+protection toggles + (sliders) ....................... */
- /* reset offset - now goes from RHS of panel */
- offset = (int)rect->xmax;
-
- // TODO: when drawing sliders, make those draw instead of these toggles if not enough space
- if (v2d && !is_being_renamed) {
- short draw_sliders = 0;
-
- /* check if we need to show the sliders */
- if ((ac->sl) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_GRAPH)) {
- switch (ac->spacetype) {
- case SPACE_ACTION:
- {
- SpaceAction *saction = (SpaceAction *)ac->sl;
- draw_sliders = (saction->flag & SACTION_SLIDERS);
- break;
- }
- case SPACE_GRAPH:
- {
- SpaceGraph *sipo = (SpaceGraph *)ac->sl;
- draw_sliders = (sipo->flag & SIPO_SLIDERS);
- break;
- }
- }
- }
-
- /* check if there's enough space for the toggles if the sliders are drawn too */
- if (!(draw_sliders) || (BLI_rcti_size_x(&v2d->mask) > ACHANNEL_BUTTON_WIDTH / 2) ) {
- /* protect... */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT)) {
- offset -= ICON_WIDTH;
- draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_PROTECT);
- }
- /* mute... */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE)) {
- offset -= ICON_WIDTH;
- draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_MUTE);
- }
- if (ale->type == ANIMTYPE_GPLAYER) {
- /* Not technically "mute" (in terms of anim channels, but this sets layer visibility instead) */
- offset -= ICON_WIDTH;
- draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_VISIBLE);
- }
-
- /* modifiers disable */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MOD_OFF)) {
- /* hack: extra spacing, to avoid touching the mute toggle */
- offset -= ICON_WIDTH * 1.2f;
- draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_MOD_OFF);
- }
-
- /* ----------- */
-
- /* pinned... */
- if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PINNED)) {
- offset -= ICON_WIDTH;
- draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_PINNED);
- }
-
- /* NLA Action "pushdown" */
- if ((ale->type == ANIMTYPE_NLAACTION) && (ale->adt && ale->adt->action) && !(ale->adt->flag & ADT_NLA_EDIT_ON)) {
- uiBut *but;
- PointerRNA *opptr_b;
-
- UI_block_emboss_set(block, UI_EMBOSS);
-
- offset -= UI_UNIT_X;
- but = uiDefIconButO(block, UI_BTYPE_BUT, "NLA_OT_action_pushdown", WM_OP_INVOKE_DEFAULT, ICON_NLA_PUSHDOWN,
- offset, ymid, UI_UNIT_X, UI_UNIT_X, NULL);
-
- opptr_b = UI_but_operator_ptr_get(but);
- RNA_int_set(opptr_b, "channel_index", channel_index);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
- }
- }
-
- /* draw slider
- * - even if we can draw sliders for this view, we must also check that the channel-type supports them
- * (only only F-Curves really can support them for now)
- * - to make things easier, we use RNA-autobuts for this so that changes are reflected immediately,
- * wherever they occurred. BUT, we don't use the layout engine, otherwise we'd get wrong alignment,
- * and wouldn't be able to auto-keyframe...
- * - 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)) {
- /* adjust offset */
- // TODO: make slider width dynamic, so that they can be easier to use when the view is wide enough
- offset -= SLIDER_WIDTH;
-
- /* need backdrop behind sliders... */
- UI_block_emboss_set(block, UI_EMBOSS);
-
- if (ale->owner) { /* Slider using custom RNA Access ---------- */
- if (ale->type == ANIMTYPE_NLACURVE) {
- NlaStrip *strip = (NlaStrip *)ale->owner;
- FCurve *fcu = (FCurve *)ale->data;
- PointerRNA ptr;
- PropertyRNA *prop;
-
- /* create RNA pointers */
- RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, &ptr);
- prop = RNA_struct_find_property(&ptr, fcu->rna_path);
-
- /* create property slider */
- if (prop) {
- uiBut *but;
-
- /* create the slider button, and assign relevant callback to ensure keyframes are inserted... */
- but = uiDefAutoButR(block, &ptr, prop, fcu->array_index, "", ICON_NONE, offset, ymid, SLIDER_WIDTH, channel_height);
- UI_but_func_set(but, achannel_setting_slider_nla_curve_cb, ale->id, ale->data);
- }
- }
- }
- else if (ale->id) { /* Slider using RNA Access --------------- */
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
- char *rna_path = NULL;
- int array_index = 0;
- short free_path = 0;
-
- /* get destination info */
- if (ale->type == ANIMTYPE_FCURVE) {
- FCurve *fcu = (FCurve *)ale->data;
-
- rna_path = fcu->rna_path;
- array_index = fcu->array_index;
- }
- else if (ale->type == ANIMTYPE_SHAPEKEY) {
- KeyBlock *kb = (KeyBlock *)ale->data;
- Key *key = (Key *)ale->id;
-
- rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
- free_path = 1;
- }
-
- /* only if RNA-Path found */
- if (rna_path) {
- /* get RNA pointer, and resolve the path */
- RNA_id_pointer_create(ale->id, &id_ptr);
-
- /* try to resolve the path */
- if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop)) {
- uiBut *but;
-
- /* create the slider button, and assign relevant callback to ensure keyframes are inserted... */
- but = uiDefAutoButR(block, &ptr, prop, array_index, "", ICON_NONE, offset, ymid, SLIDER_WIDTH, channel_height);
-
- /* assign keyframing function according to slider type */
- if (ale->type == ANIMTYPE_SHAPEKEY)
- UI_but_func_set(but, achannel_setting_slider_shapekey_cb, ale->id, ale->data);
- else
- UI_but_func_set(but, achannel_setting_slider_cb, ale->id, ale->data);
- }
-
- /* free the path if necessary */
- if (free_path)
- MEM_freeN(rna_path);
- }
- }
- else { /* Special Slider for stuff without RNA Access ---------- */
- // TODO: only implement this case when we really need it...
- }
- }
- }
+ }
+ }
+
+ /* step 4) draw text - check if renaming widget is in use... */
+ if (is_being_renamed) {
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+
+ /* draw renaming widget if we can get RNA pointer for it
+ * NOTE: property may only be available in some cases, even if we have
+ * a callback available (e.g. broken F-Curve rename)
+ */
+ if (acf->name_prop(ale, &ptr, &prop)) {
+ const short margin_x = 3 * round_fl_to_int(UI_DPI_FAC);
+ const short width = ac->ar->winx - offset - (margin_x * 2);
+ uiBut *but;
+
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ but = uiDefButR(block,
+ UI_BTYPE_TEXT,
+ 1,
+ "",
+ offset + margin_x,
+ rect->ymin,
+ MAX2(width, RENAME_TEXT_MIN_WIDTH),
+ channel_height,
+ &ptr,
+ RNA_property_identifier(prop),
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+
+ /* copy what outliner does here, see outliner_buttons */
+ if (UI_but_active_only(C, ac->ar, block, but) == false) {
+ ac->ads->renameIndex = 0;
+
+ /* send notifiers */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_RENAME, NULL);
+ }
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ }
+ else {
+ /* Cannot get property/cannot or rename for some reason, so clear rename index
+ * so that this doesn't hang around, and the name can be drawn normally - T47492
+ */
+ ac->ads->renameIndex = 0;
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN, NULL);
+ }
+ }
+
+ /* step 5) draw mute+protection toggles + (sliders) ....................... */
+ /* reset offset - now goes from RHS of panel */
+ offset = (int)rect->xmax;
+
+ // TODO: when drawing sliders, make those draw instead of these toggles if not enough space
+ if (v2d && !is_being_renamed) {
+ short draw_sliders = 0;
+
+ /* check if we need to show the sliders */
+ if ((ac->sl) && ELEM(ac->spacetype, SPACE_ACTION, SPACE_GRAPH)) {
+ switch (ac->spacetype) {
+ case SPACE_ACTION: {
+ SpaceAction *saction = (SpaceAction *)ac->sl;
+ draw_sliders = (saction->flag & SACTION_SLIDERS);
+ break;
+ }
+ case SPACE_GRAPH: {
+ SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ draw_sliders = (sipo->flag & SIPO_SLIDERS);
+ break;
+ }
+ }
+ }
+
+ /* check if there's enough space for the toggles if the sliders are drawn too */
+ if (!(draw_sliders) || (BLI_rcti_size_x(&v2d->mask) > ACHANNEL_BUTTON_WIDTH / 2)) {
+ /* protect... */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PROTECT)) {
+ offset -= ICON_WIDTH;
+ draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_PROTECT);
+ }
+ /* mute... */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MUTE)) {
+ offset -= ICON_WIDTH;
+ draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_MUTE);
+ }
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ /* Not technically "mute" (in terms of anim channels, but this sets layer visibility instead) */
+ offset -= ICON_WIDTH;
+ draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_VISIBLE);
+ }
+
+ /* modifiers disable */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_MOD_OFF)) {
+ /* hack: extra spacing, to avoid touching the mute toggle */
+ offset -= ICON_WIDTH * 1.2f;
+ draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_MOD_OFF);
+ }
+
+ /* ----------- */
+
+ /* pinned... */
+ if (acf->has_setting(ac, ale, ACHANNEL_SETTING_PINNED)) {
+ offset -= ICON_WIDTH;
+ draw_setting_widget(ac, ale, acf, block, offset, ymid, ACHANNEL_SETTING_PINNED);
+ }
+
+ /* NLA Action "pushdown" */
+ if ((ale->type == ANIMTYPE_NLAACTION) && (ale->adt && ale->adt->action) &&
+ !(ale->adt->flag & ADT_NLA_EDIT_ON)) {
+ uiBut *but;
+ PointerRNA *opptr_b;
+
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ offset -= UI_UNIT_X;
+ but = uiDefIconButO(block,
+ UI_BTYPE_BUT,
+ "NLA_OT_action_pushdown",
+ WM_OP_INVOKE_DEFAULT,
+ ICON_NLA_PUSHDOWN,
+ offset,
+ ymid,
+ UI_UNIT_X,
+ UI_UNIT_X,
+ NULL);
+
+ opptr_b = UI_but_operator_ptr_get(but);
+ RNA_int_set(opptr_b, "channel_index", channel_index);
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ }
+ }
+
+ /* draw slider
+ * - even if we can draw sliders for this view, we must also check that the channel-type supports them
+ * (only only F-Curves really can support them for now)
+ * - to make things easier, we use RNA-autobuts for this so that changes are reflected immediately,
+ * wherever they occurred. BUT, we don't use the layout engine, otherwise we'd get wrong alignment,
+ * and wouldn't be able to auto-keyframe...
+ * - 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)) {
+ /* adjust offset */
+ // TODO: make slider width dynamic, so that they can be easier to use when the view is wide enough
+ offset -= SLIDER_WIDTH;
+
+ /* need backdrop behind sliders... */
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ if (ale->owner) { /* Slider using custom RNA Access ---------- */
+ if (ale->type == ANIMTYPE_NLACURVE) {
+ NlaStrip *strip = (NlaStrip *)ale->owner;
+ FCurve *fcu = (FCurve *)ale->data;
+ PointerRNA ptr;
+ PropertyRNA *prop;
+
+ /* create RNA pointers */
+ RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, &ptr);
+ prop = RNA_struct_find_property(&ptr, fcu->rna_path);
+
+ /* create property slider */
+ if (prop) {
+ uiBut *but;
+
+ /* create the slider button, and assign relevant callback to ensure keyframes are inserted... */
+ but = uiDefAutoButR(block,
+ &ptr,
+ prop,
+ fcu->array_index,
+ "",
+ ICON_NONE,
+ offset,
+ ymid,
+ SLIDER_WIDTH,
+ channel_height);
+ UI_but_func_set(but, achannel_setting_slider_nla_curve_cb, ale->id, ale->data);
+ }
+ }
+ }
+ else if (ale->id) { /* Slider using RNA Access --------------- */
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ char *rna_path = NULL;
+ int array_index = 0;
+ short free_path = 0;
+
+ /* get destination info */
+ if (ale->type == ANIMTYPE_FCURVE) {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ rna_path = fcu->rna_path;
+ array_index = fcu->array_index;
+ }
+ else if (ale->type == ANIMTYPE_SHAPEKEY) {
+ KeyBlock *kb = (KeyBlock *)ale->data;
+ Key *key = (Key *)ale->id;
+
+ rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
+ free_path = 1;
+ }
+
+ /* only if RNA-Path found */
+ if (rna_path) {
+ /* get RNA pointer, and resolve the path */
+ RNA_id_pointer_create(ale->id, &id_ptr);
+
+ /* try to resolve the path */
+ if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop)) {
+ uiBut *but;
+
+ /* create the slider button, and assign relevant callback to ensure keyframes are inserted... */
+ but = uiDefAutoButR(block,
+ &ptr,
+ prop,
+ array_index,
+ "",
+ ICON_NONE,
+ offset,
+ ymid,
+ SLIDER_WIDTH,
+ channel_height);
+
+ /* assign keyframing function according to slider type */
+ if (ale->type == ANIMTYPE_SHAPEKEY)
+ UI_but_func_set(but, achannel_setting_slider_shapekey_cb, ale->id, ale->data);
+ else
+ UI_but_func_set(but, achannel_setting_slider_cb, ale->id, ale->data);
+ }
+
+ /* free the path if necessary */
+ if (free_path)
+ MEM_freeN(rna_path);
+ }
+ }
+ else { /* Special Slider for stuff without RNA Access ---------- */
+ // TODO: only implement this case when we really need it...
+ }
+ }
+ }
}
/* *********************************************** */
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index 558c5d5bfc1..c2878a64e97 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -59,7 +58,7 @@
#include "ED_anim_api.h"
#include "ED_armature.h"
-#include "ED_keyframes_edit.h" // XXX move the select modes out of there!
+#include "ED_keyframes_edit.h" // XXX move the select modes out of there!
#include "ED_object.h"
#include "ED_screen.h"
#include "ED_select_utils.h"
@@ -74,178 +73,173 @@
/* Set the given animation-channel as the active one for the active context */
// TODO: extend for animdata types...
-void ANIM_set_active_channel(bAnimContext *ac, void *data, eAnimCont_Types datatype, eAnimFilter_Flags filter, void *channel_data, eAnim_ChannelType channel_type)
-{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
-
- /* try to build list of filtered items */
- ANIM_animdata_filter(ac, &anim_data, filter, data, datatype);
- if (BLI_listbase_is_empty(&anim_data))
- return;
-
- /* only clear the 'active' flag for the channels of the same type */
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* skip if types don't match */
- if (channel_type != ale->type)
- continue;
-
- /* flag to set depends on type */
- switch (ale->type) {
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = (bActionGroup *)ale->data;
-
- ACHANNEL_SET_FLAG(agrp, ACHANNEL_SETFLAG_CLEAR, AGRP_ACTIVE);
- break;
- }
- case ANIMTYPE_FCURVE:
- case ANIMTYPE_NLACURVE:
- {
- FCurve *fcu = (FCurve *)ale->data;
-
- ACHANNEL_SET_FLAG(fcu, ACHANNEL_SETFLAG_CLEAR, FCURVE_ACTIVE);
- break;
- }
- case ANIMTYPE_NLATRACK:
- {
- NlaTrack *nlt = (NlaTrack *)ale->data;
-
- ACHANNEL_SET_FLAG(nlt, ACHANNEL_SETFLAG_CLEAR, NLATRACK_ACTIVE);
- break;
- }
- case ANIMTYPE_FILLACTD: /* Action Expander */
- case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
- case ANIMTYPE_DSLAM:
- case ANIMTYPE_DSCAM:
- case ANIMTYPE_DSCACHEFILE:
- case ANIMTYPE_DSCUR:
- case ANIMTYPE_DSSKEY:
- case ANIMTYPE_DSWOR:
- case ANIMTYPE_DSPART:
- case ANIMTYPE_DSMBALL:
- case ANIMTYPE_DSARM:
- case ANIMTYPE_DSMESH:
- case ANIMTYPE_DSTEX:
- case ANIMTYPE_DSLAT:
- case ANIMTYPE_DSLINESTYLE:
- case ANIMTYPE_DSSPK:
- case ANIMTYPE_DSGPENCIL:
- case ANIMTYPE_DSMCLIP:
- {
- /* need to verify that this data is valid for now */
- if (ale->adt) {
- ACHANNEL_SET_FLAG(ale->adt, ACHANNEL_SETFLAG_CLEAR, ADT_UI_ACTIVE);
- }
- break;
- }
- case ANIMTYPE_GPLAYER:
- {
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
- ACHANNEL_SET_FLAG(gpl, ACHANNEL_SETFLAG_CLEAR, GP_LAYER_ACTIVE);
- break;
- }
- }
- }
-
- /* set active flag */
- if (channel_data) {
- switch (channel_type) {
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = (bActionGroup *)channel_data;
- agrp->flag |= AGRP_ACTIVE;
- break;
- }
- case ANIMTYPE_FCURVE:
- case ANIMTYPE_NLACURVE:
- {
- FCurve *fcu = (FCurve *)channel_data;
- fcu->flag |= FCURVE_ACTIVE;
- break;
- }
- case ANIMTYPE_NLATRACK:
- {
- NlaTrack *nlt = (NlaTrack *)channel_data;
- nlt->flag |= NLATRACK_ACTIVE;
- break;
- }
- case ANIMTYPE_FILLACTD: /* Action Expander */
- case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
- case ANIMTYPE_DSLAM:
- case ANIMTYPE_DSCAM:
- case ANIMTYPE_DSCACHEFILE:
- case ANIMTYPE_DSCUR:
- case ANIMTYPE_DSSKEY:
- case ANIMTYPE_DSWOR:
- case ANIMTYPE_DSPART:
- case ANIMTYPE_DSMBALL:
- case ANIMTYPE_DSARM:
- case ANIMTYPE_DSMESH:
- case ANIMTYPE_DSLAT:
- case ANIMTYPE_DSLINESTYLE:
- case ANIMTYPE_DSSPK:
- case ANIMTYPE_DSNTREE:
- case ANIMTYPE_DSTEX:
- case ANIMTYPE_DSGPENCIL:
- case ANIMTYPE_DSMCLIP:
- {
- /* need to verify that this data is valid for now */
- if (ale && ale->adt) {
- ale->adt->flag |= ADT_UI_ACTIVE;
- }
- break;
- }
-
- case ANIMTYPE_GPLAYER:
- {
- bGPDlayer *gpl = (bGPDlayer *)channel_data;
- gpl->flag |= GP_LAYER_ACTIVE;
- break;
- }
-
- /* unhandled currently, but may be interesting */
- case ANIMTYPE_MASKLAYER:
- case ANIMTYPE_SHAPEKEY:
- case ANIMTYPE_NLAACTION:
- break;
-
- /* other types */
- default:
- break;
- }
- }
-
- /* clean up */
- ANIM_animdata_freelist(&anim_data);
+void ANIM_set_active_channel(bAnimContext *ac,
+ void *data,
+ eAnimCont_Types datatype,
+ eAnimFilter_Flags filter,
+ void *channel_data,
+ eAnim_ChannelType channel_type)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+
+ /* try to build list of filtered items */
+ ANIM_animdata_filter(ac, &anim_data, filter, data, datatype);
+ if (BLI_listbase_is_empty(&anim_data))
+ return;
+
+ /* only clear the 'active' flag for the channels of the same type */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* skip if types don't match */
+ if (channel_type != ale->type)
+ continue;
+
+ /* flag to set depends on type */
+ switch (ale->type) {
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+
+ ACHANNEL_SET_FLAG(agrp, ACHANNEL_SETFLAG_CLEAR, AGRP_ACTIVE);
+ break;
+ }
+ case ANIMTYPE_FCURVE:
+ case ANIMTYPE_NLACURVE: {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ ACHANNEL_SET_FLAG(fcu, ACHANNEL_SETFLAG_CLEAR, FCURVE_ACTIVE);
+ break;
+ }
+ case ANIMTYPE_NLATRACK: {
+ NlaTrack *nlt = (NlaTrack *)ale->data;
+
+ ACHANNEL_SET_FLAG(nlt, ACHANNEL_SETFLAG_CLEAR, NLATRACK_ACTIVE);
+ break;
+ }
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCACHEFILE:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ case ANIMTYPE_DSMESH:
+ case ANIMTYPE_DSTEX:
+ case ANIMTYPE_DSLAT:
+ case ANIMTYPE_DSLINESTYLE:
+ case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
+ case ANIMTYPE_DSMCLIP: {
+ /* need to verify that this data is valid for now */
+ if (ale->adt) {
+ ACHANNEL_SET_FLAG(ale->adt, ACHANNEL_SETFLAG_CLEAR, ADT_UI_ACTIVE);
+ }
+ break;
+ }
+ case ANIMTYPE_GPLAYER: {
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ ACHANNEL_SET_FLAG(gpl, ACHANNEL_SETFLAG_CLEAR, GP_LAYER_ACTIVE);
+ break;
+ }
+ }
+ }
+
+ /* set active flag */
+ if (channel_data) {
+ switch (channel_type) {
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = (bActionGroup *)channel_data;
+ agrp->flag |= AGRP_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_FCURVE:
+ case ANIMTYPE_NLACURVE: {
+ FCurve *fcu = (FCurve *)channel_data;
+ fcu->flag |= FCURVE_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_NLATRACK: {
+ NlaTrack *nlt = (NlaTrack *)channel_data;
+ nlt->flag |= NLATRACK_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCACHEFILE:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ case ANIMTYPE_DSMESH:
+ case ANIMTYPE_DSLAT:
+ case ANIMTYPE_DSLINESTYLE:
+ case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSNTREE:
+ case ANIMTYPE_DSTEX:
+ case ANIMTYPE_DSGPENCIL:
+ case ANIMTYPE_DSMCLIP: {
+ /* need to verify that this data is valid for now */
+ if (ale && ale->adt) {
+ ale->adt->flag |= ADT_UI_ACTIVE;
+ }
+ break;
+ }
+
+ case ANIMTYPE_GPLAYER: {
+ bGPDlayer *gpl = (bGPDlayer *)channel_data;
+ gpl->flag |= GP_LAYER_ACTIVE;
+ break;
+ }
+
+ /* unhandled currently, but may be interesting */
+ case ANIMTYPE_MASKLAYER:
+ case ANIMTYPE_SHAPEKEY:
+ case ANIMTYPE_NLAACTION:
+ break;
+
+ /* other types */
+ default:
+ break;
+ }
+ }
+
+ /* clean up */
+ ANIM_animdata_freelist(&anim_data);
}
static void select_pchan_for_action_group(bAnimContext *ac, bActionGroup *agrp, bAnimListElem *ale)
{
- /* Armatures-Specific Feature:
- * See mouse_anim_channels() -> ANIMTYPE_GROUP case for more details (T38737)
- */
- if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) {
- if ((ale->id) && (GS(ale->id->name) == ID_OB)) {
- Object *ob = (Object *)ale->id;
- if (ob->type == OB_ARMATURE) {
- /* Assume for now that any group with corresponding name is what we want
- * (i.e. for an armature whose location is animated, things would break
- * if the user were to add a bone named "Location").
- *
- * TODO: check the first F-Curve or so to be sure...
- */
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
- if (agrp->flag & AGRP_SELECTED) {
- ED_pose_bone_select(ob, pchan, true);
- }
- else {
- ED_pose_bone_select(ob, pchan, false);
- }
- }
- }
- }
+ /* Armatures-Specific Feature:
+ * See mouse_anim_channels() -> ANIMTYPE_GROUP case for more details (T38737)
+ */
+ if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) {
+ if ((ale->id) && (GS(ale->id->name) == ID_OB)) {
+ Object *ob = (Object *)ale->id;
+ if (ob->type == OB_ARMATURE) {
+ /* Assume for now that any group with corresponding name is what we want
+ * (i.e. for an armature whose location is animated, things would break
+ * if the user were to add a bone named "Location").
+ *
+ * TODO: check the first F-Curve or so to be sure...
+ */
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
+ if (agrp->flag & AGRP_SELECTED) {
+ ED_pose_bone_select(ob, pchan, true);
+ }
+ else {
+ ED_pose_bone_select(ob, pchan, false);
+ }
+ }
+ }
+ }
}
/* Deselect all animation channels
@@ -254,195 +248,186 @@ static void select_pchan_for_action_group(bAnimContext *ac, bActionGroup *agrp,
* - test: check if deselecting instead of selecting
* - sel: eAnimChannels_SetFlag;
*/
-void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types datatype, bool test, eAnimChannels_SetFlag sel)
-{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* filter data */
- /* NOTE: no list visible, otherwise, we get dangling */
- filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
- ANIM_animdata_filter(ac, &anim_data, filter, data, datatype);
-
- /* See if we should be selecting or deselecting */
- if (test) {
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (sel == 0)
- break;
-
- switch (ale->type) {
- case ANIMTYPE_SCENE:
- if (ale->flag & SCE_DS_SELECTED)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- case ANIMTYPE_OBJECT:
-#if 0 /* for now, do not take object selection into account, since it gets too annoying */
- if (ale->flag & SELECT)
- sel = ACHANNEL_SETFLAG_CLEAR;
+void ANIM_deselect_anim_channels(
+ bAnimContext *ac, void *data, eAnimCont_Types datatype, bool test, eAnimChannels_SetFlag sel)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* filter data */
+ /* NOTE: no list visible, otherwise, we get dangling */
+ filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
+ ANIM_animdata_filter(ac, &anim_data, filter, data, datatype);
+
+ /* See if we should be selecting or deselecting */
+ if (test) {
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (sel == 0)
+ break;
+
+ switch (ale->type) {
+ case ANIMTYPE_SCENE:
+ if (ale->flag & SCE_DS_SELECTED)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ case ANIMTYPE_OBJECT:
+#if 0 /* for now, do not take object selection into account, since it gets too annoying */
+ if (ale->flag & SELECT)
+ sel = ACHANNEL_SETFLAG_CLEAR;
#endif
- break;
- case ANIMTYPE_GROUP:
- if (ale->flag & AGRP_SELECTED)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- case ANIMTYPE_FCURVE:
- case ANIMTYPE_NLACURVE:
- if (ale->flag & FCURVE_SELECTED)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- case ANIMTYPE_SHAPEKEY:
- if (ale->flag & KEYBLOCK_SEL)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- case ANIMTYPE_NLATRACK:
- if (ale->flag & NLATRACK_SELECTED)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
-
- case ANIMTYPE_FILLACTD: /* Action Expander */
- case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
- case ANIMTYPE_DSLAM:
- case ANIMTYPE_DSCAM:
- case ANIMTYPE_DSCACHEFILE:
- case ANIMTYPE_DSCUR:
- case ANIMTYPE_DSSKEY:
- case ANIMTYPE_DSWOR:
- case ANIMTYPE_DSPART:
- case ANIMTYPE_DSMBALL:
- case ANIMTYPE_DSARM:
- case ANIMTYPE_DSMESH:
- case ANIMTYPE_DSNTREE:
- case ANIMTYPE_DSTEX:
- case ANIMTYPE_DSLAT:
- case ANIMTYPE_DSLINESTYLE:
- case ANIMTYPE_DSSPK:
- case ANIMTYPE_DSGPENCIL:
- case ANIMTYPE_DSMCLIP:
- {
- if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- }
- case ANIMTYPE_GPLAYER:
- if (ale->flag & GP_LAYER_SELECT)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- case ANIMTYPE_MASKLAYER:
- if (ale->flag & MASK_LAYERFLAG_SELECT)
- sel = ACHANNEL_SETFLAG_CLEAR;
- break;
- }
- }
- }
-
- /* Now set the flags */
- for (ale = anim_data.first; ale; ale = ale->next) {
- switch (ale->type) {
- case ANIMTYPE_SCENE:
- {
- Scene *scene = (Scene *)ale->data;
-
- ACHANNEL_SET_FLAG(scene, sel, SCE_DS_SELECTED);
-
- if (scene->adt) {
- ACHANNEL_SET_FLAG(scene, sel, ADT_UI_SELECTED);
- }
- break;
- }
- case ANIMTYPE_OBJECT:
- {
-#if 0 /* for now, do not take object selection into account, since it gets too annoying */
- Base *base = (Base *)ale->data;
- Object *ob = base->object;
-
- ACHANNEL_SET_FLAG(base, sel, SELECT);
- ACHANNEL_SET_FLAG(ob, sel, SELECT);
-
- if (ob->adt) {
- ACHANNEL_SET_FLAG(ob, sel, ADT_UI_SELECTED);
- }
+ break;
+ case ANIMTYPE_GROUP:
+ if (ale->flag & AGRP_SELECTED)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ case ANIMTYPE_FCURVE:
+ case ANIMTYPE_NLACURVE:
+ if (ale->flag & FCURVE_SELECTED)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ case ANIMTYPE_SHAPEKEY:
+ if (ale->flag & KEYBLOCK_SEL)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ case ANIMTYPE_NLATRACK:
+ if (ale->flag & NLATRACK_SELECTED)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCACHEFILE:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ case ANIMTYPE_DSMESH:
+ case ANIMTYPE_DSNTREE:
+ case ANIMTYPE_DSTEX:
+ case ANIMTYPE_DSLAT:
+ case ANIMTYPE_DSLINESTYLE:
+ case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
+ case ANIMTYPE_DSMCLIP: {
+ if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ }
+ case ANIMTYPE_GPLAYER:
+ if (ale->flag & GP_LAYER_SELECT)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ case ANIMTYPE_MASKLAYER:
+ if (ale->flag & MASK_LAYERFLAG_SELECT)
+ sel = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ }
+ }
+ }
+
+ /* Now set the flags */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ switch (ale->type) {
+ case ANIMTYPE_SCENE: {
+ Scene *scene = (Scene *)ale->data;
+
+ ACHANNEL_SET_FLAG(scene, sel, SCE_DS_SELECTED);
+
+ if (scene->adt) {
+ ACHANNEL_SET_FLAG(scene, sel, ADT_UI_SELECTED);
+ }
+ break;
+ }
+ case ANIMTYPE_OBJECT: {
+#if 0 /* for now, do not take object selection into account, since it gets too annoying */
+ Base *base = (Base *)ale->data;
+ Object *ob = base->object;
+
+ ACHANNEL_SET_FLAG(base, sel, SELECT);
+ ACHANNEL_SET_FLAG(ob, sel, SELECT);
+
+ if (ob->adt) {
+ ACHANNEL_SET_FLAG(ob, sel, ADT_UI_SELECTED);
+ }
#endif
- break;
- }
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = (bActionGroup *)ale->data;
- ACHANNEL_SET_FLAG(agrp, sel, AGRP_SELECTED);
- select_pchan_for_action_group(ac, agrp, ale);
- agrp->flag &= ~AGRP_ACTIVE;
- break;
- }
- case ANIMTYPE_FCURVE:
- case ANIMTYPE_NLACURVE:
- {
- FCurve *fcu = (FCurve *)ale->data;
-
- ACHANNEL_SET_FLAG(fcu, sel, FCURVE_SELECTED);
- fcu->flag &= ~FCURVE_ACTIVE;
- break;
- }
- case ANIMTYPE_SHAPEKEY:
- {
- KeyBlock *kb = (KeyBlock *)ale->data;
-
- ACHANNEL_SET_FLAG(kb, sel, KEYBLOCK_SEL);
- break;
- }
- case ANIMTYPE_NLATRACK:
- {
- NlaTrack *nlt = (NlaTrack *)ale->data;
-
- ACHANNEL_SET_FLAG(nlt, sel, NLATRACK_SELECTED);
- nlt->flag &= ~NLATRACK_ACTIVE;
- break;
- }
- case ANIMTYPE_FILLACTD: /* Action Expander */
- case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
- case ANIMTYPE_DSLAM:
- case ANIMTYPE_DSCAM:
- case ANIMTYPE_DSCACHEFILE:
- case ANIMTYPE_DSCUR:
- case ANIMTYPE_DSSKEY:
- case ANIMTYPE_DSWOR:
- case ANIMTYPE_DSPART:
- case ANIMTYPE_DSMBALL:
- case ANIMTYPE_DSARM:
- case ANIMTYPE_DSMESH:
- case ANIMTYPE_DSNTREE:
- case ANIMTYPE_DSTEX:
- case ANIMTYPE_DSLAT:
- case ANIMTYPE_DSLINESTYLE:
- case ANIMTYPE_DSSPK:
- case ANIMTYPE_DSGPENCIL:
- case ANIMTYPE_DSMCLIP:
- {
- /* need to verify that this data is valid for now */
- if (ale->adt) {
- ACHANNEL_SET_FLAG(ale->adt, sel, ADT_UI_SELECTED);
- ale->adt->flag &= ~ADT_UI_ACTIVE;
- }
- break;
- }
- case ANIMTYPE_GPLAYER:
- {
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
- ACHANNEL_SET_FLAG(gpl, sel, GP_LAYER_SELECT);
- break;
- }
- case ANIMTYPE_MASKLAYER:
- {
- MaskLayer *masklay = (MaskLayer *)ale->data;
-
- ACHANNEL_SET_FLAG(masklay, sel, MASK_LAYERFLAG_SELECT);
- break;
- }
- }
- }
-
- /* Cleanup */
- ANIM_animdata_freelist(&anim_data);
+ break;
+ }
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+ ACHANNEL_SET_FLAG(agrp, sel, AGRP_SELECTED);
+ select_pchan_for_action_group(ac, agrp, ale);
+ agrp->flag &= ~AGRP_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_FCURVE:
+ case ANIMTYPE_NLACURVE: {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ ACHANNEL_SET_FLAG(fcu, sel, FCURVE_SELECTED);
+ fcu->flag &= ~FCURVE_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_SHAPEKEY: {
+ KeyBlock *kb = (KeyBlock *)ale->data;
+
+ ACHANNEL_SET_FLAG(kb, sel, KEYBLOCK_SEL);
+ break;
+ }
+ case ANIMTYPE_NLATRACK: {
+ NlaTrack *nlt = (NlaTrack *)ale->data;
+
+ ACHANNEL_SET_FLAG(nlt, sel, NLATRACK_SELECTED);
+ nlt->flag &= ~NLATRACK_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCACHEFILE:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ case ANIMTYPE_DSMESH:
+ case ANIMTYPE_DSNTREE:
+ case ANIMTYPE_DSTEX:
+ case ANIMTYPE_DSLAT:
+ case ANIMTYPE_DSLINESTYLE:
+ case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
+ case ANIMTYPE_DSMCLIP: {
+ /* need to verify that this data is valid for now */
+ if (ale->adt) {
+ ACHANNEL_SET_FLAG(ale->adt, sel, ADT_UI_SELECTED);
+ ale->adt->flag &= ~ADT_UI_ACTIVE;
+ }
+ break;
+ }
+ case ANIMTYPE_GPLAYER: {
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ ACHANNEL_SET_FLAG(gpl, sel, GP_LAYER_SELECT);
+ break;
+ }
+ case ANIMTYPE_MASKLAYER: {
+ MaskLayer *masklay = (MaskLayer *)ale->data;
+
+ ACHANNEL_SET_FLAG(masklay, sel, MASK_LAYERFLAG_SELECT);
+ break;
+ }
+ }
+ }
+
+ /* Cleanup */
+ ANIM_animdata_freelist(&anim_data);
}
/* ---------------------------- Graph Editor ------------------------------------- */
@@ -456,137 +441,140 @@ void ANIM_deselect_anim_channels(bAnimContext *ac, void *data, eAnimCont_Types d
* - setting: type of setting to set
* - on: whether the visibility setting has been enabled or disabled
*/
-void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAnimListElem *ale_setting, eAnimChannel_Settings setting, eAnimChannels_SetFlag mode)
-{
- bAnimListElem *ale, *match = NULL;
- int prevLevel = 0, matchLevel = 0;
-
- /* sanity check */
- if (ELEM(NULL, anim_data, anim_data->first))
- return;
-
- if (setting == ACHANNEL_SETTING_ALWAYS_VISIBLE) {
- return;
- }
-
- /* find the channel that got changed */
- for (ale = anim_data->first; ale; ale = ale->next) {
- /* compare data, and type as main way of identifying the channel */
- if ((ale->data == ale_setting->data) && (ale->type == ale_setting->type)) {
- /* we also have to check the ID, this is assigned to, since a block may have multiple users */
- /* TODO: is the owner-data more revealing? */
- if (ale->id == ale_setting->id) {
- match = ale;
- break;
- }
- }
- }
- if (match == NULL) {
- printf("ERROR: no channel matching the one changed was found\n");
- return;
- }
- else {
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale_setting);
-
- if (acf == NULL) {
- printf("ERROR: no channel info for the changed channel\n");
- return;
- }
-
- /* get the level of the channel that was affected
- * - we define the level as simply being the offset for the start of the channel
- */
- matchLevel = (acf->get_offset) ? acf->get_offset(ac, ale_setting) : 0;
- prevLevel = matchLevel;
- }
-
- /* flush up?
- *
- * For Visibility:
- * - only flush up if the current state is now enabled (positive 'on' state is default)
- * (otherwise, it's too much work to force the parents to be inactive too)
- *
- * For everything else:
- * - only flush up if the current state is now disabled (negative 'off' state is default)
- * (otherwise, it's too much work to force the parents to be active too)
- */
- if ( ((setting == ACHANNEL_SETTING_VISIBLE) && (mode != ACHANNEL_SETFLAG_CLEAR)) ||
- ((setting != ACHANNEL_SETTING_VISIBLE) && (mode == ACHANNEL_SETFLAG_CLEAR)))
- {
- /* go backwards in the list, until the highest-ranking element (by indention has been covered) */
- for (ale = match->prev; ale; ale = ale->prev) {
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- int level;
-
- /* if no channel info was found, skip, since this type might not have any useful info */
- if (acf == NULL)
- continue;
-
- /* get the level of the current channel traversed
- * - we define the level as simply being the offset for the start of the channel
- */
- level = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
-
- /* if the level is 'less than' (i.e. more important) the level we're matching
- * but also 'less than' the level just tried (i.e. only the 1st group above grouped F-Curves,
- * when toggling visibility of F-Curves, gets flushed, which should happen if we don't let prevLevel
- * get updated below once the first 1st group is found)...
- */
- if (level < prevLevel) {
- /* flush the new status... */
- ANIM_channel_setting_set(ac, ale, setting, mode);
-
- /* store this level as the 'old' level now */
- prevLevel = level;
- }
- /* if the level is 'greater than' (i.e. less important) than the previous level... */
- else if (level > prevLevel) {
- /* if previous level was a base-level (i.e. 0 offset / root of one hierarchy),
- * stop here
- */
- if (prevLevel == 0)
- break;
- /* otherwise, this level weaves into another sibling hierarchy to the previous one just
- * finished, so skip until we get to the parent of this level
- */
- else
- continue;
- }
- }
- }
-
- /* flush down (always) */
- {
- /* go forwards in the list, until the lowest-ranking element (by indention has been covered) */
- for (ale = match->next; ale; ale = ale->next) {
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
- int level;
-
- /* if no channel info was found, skip, since this type might not have any useful info */
- if (acf == NULL)
- continue;
-
- /* get the level of the current channel traversed
- * - we define the level as simply being the offset for the start of the channel
- */
- level = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
-
- /* if the level is 'greater than' (i.e. less important) the channel that was changed,
- * flush the new status...
- */
- if (level > matchLevel)
- ANIM_channel_setting_set(ac, ale, setting, mode);
- /* however, if the level is 'less than or equal to' the channel that was changed,
- * (i.e. the current channel is as important if not more important than the changed channel)
- * then we should stop, since we've found the last one of the children we should flush
- */
- else
- break;
-
- /* store this level as the 'old' level now */
- // prevLevel = level; // XXX: prevLevel is unused
- }
- }
+void ANIM_flush_setting_anim_channels(bAnimContext *ac,
+ ListBase *anim_data,
+ bAnimListElem *ale_setting,
+ eAnimChannel_Settings setting,
+ eAnimChannels_SetFlag mode)
+{
+ bAnimListElem *ale, *match = NULL;
+ int prevLevel = 0, matchLevel = 0;
+
+ /* sanity check */
+ if (ELEM(NULL, anim_data, anim_data->first))
+ return;
+
+ if (setting == ACHANNEL_SETTING_ALWAYS_VISIBLE) {
+ return;
+ }
+
+ /* find the channel that got changed */
+ for (ale = anim_data->first; ale; ale = ale->next) {
+ /* compare data, and type as main way of identifying the channel */
+ if ((ale->data == ale_setting->data) && (ale->type == ale_setting->type)) {
+ /* we also have to check the ID, this is assigned to, since a block may have multiple users */
+ /* TODO: is the owner-data more revealing? */
+ if (ale->id == ale_setting->id) {
+ match = ale;
+ break;
+ }
+ }
+ }
+ if (match == NULL) {
+ printf("ERROR: no channel matching the one changed was found\n");
+ return;
+ }
+ else {
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale_setting);
+
+ if (acf == NULL) {
+ printf("ERROR: no channel info for the changed channel\n");
+ return;
+ }
+
+ /* get the level of the channel that was affected
+ * - we define the level as simply being the offset for the start of the channel
+ */
+ matchLevel = (acf->get_offset) ? acf->get_offset(ac, ale_setting) : 0;
+ prevLevel = matchLevel;
+ }
+
+ /* flush up?
+ *
+ * For Visibility:
+ * - only flush up if the current state is now enabled (positive 'on' state is default)
+ * (otherwise, it's too much work to force the parents to be inactive too)
+ *
+ * For everything else:
+ * - only flush up if the current state is now disabled (negative 'off' state is default)
+ * (otherwise, it's too much work to force the parents to be active too)
+ */
+ if (((setting == ACHANNEL_SETTING_VISIBLE) && (mode != ACHANNEL_SETFLAG_CLEAR)) ||
+ ((setting != ACHANNEL_SETTING_VISIBLE) && (mode == ACHANNEL_SETFLAG_CLEAR))) {
+ /* go backwards in the list, until the highest-ranking element (by indention has been covered) */
+ for (ale = match->prev; ale; ale = ale->prev) {
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ int level;
+
+ /* if no channel info was found, skip, since this type might not have any useful info */
+ if (acf == NULL)
+ continue;
+
+ /* get the level of the current channel traversed
+ * - we define the level as simply being the offset for the start of the channel
+ */
+ level = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+
+ /* if the level is 'less than' (i.e. more important) the level we're matching
+ * but also 'less than' the level just tried (i.e. only the 1st group above grouped F-Curves,
+ * when toggling visibility of F-Curves, gets flushed, which should happen if we don't let prevLevel
+ * get updated below once the first 1st group is found)...
+ */
+ if (level < prevLevel) {
+ /* flush the new status... */
+ ANIM_channel_setting_set(ac, ale, setting, mode);
+
+ /* store this level as the 'old' level now */
+ prevLevel = level;
+ }
+ /* if the level is 'greater than' (i.e. less important) than the previous level... */
+ else if (level > prevLevel) {
+ /* if previous level was a base-level (i.e. 0 offset / root of one hierarchy),
+ * stop here
+ */
+ if (prevLevel == 0)
+ break;
+ /* otherwise, this level weaves into another sibling hierarchy to the previous one just
+ * finished, so skip until we get to the parent of this level
+ */
+ else
+ continue;
+ }
+ }
+ }
+
+ /* flush down (always) */
+ {
+ /* go forwards in the list, until the lowest-ranking element (by indention has been covered) */
+ for (ale = match->next; ale; ale = ale->next) {
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+ int level;
+
+ /* if no channel info was found, skip, since this type might not have any useful info */
+ if (acf == NULL)
+ continue;
+
+ /* get the level of the current channel traversed
+ * - we define the level as simply being the offset for the start of the channel
+ */
+ level = (acf->get_offset) ? acf->get_offset(ac, ale) : 0;
+
+ /* if the level is 'greater than' (i.e. less important) the channel that was changed,
+ * flush the new status...
+ */
+ if (level > matchLevel)
+ ANIM_channel_setting_set(ac, ale, setting, mode);
+ /* however, if the level is 'less than or equal to' the channel that was changed,
+ * (i.e. the current channel is as important if not more important than the changed channel)
+ * then we should stop, since we've found the last one of the children we should flush
+ */
+ else
+ break;
+
+ /* store this level as the 'old' level now */
+ // prevLevel = level; // XXX: prevLevel is unused
+ }
+ }
}
/* -------------------------- F-Curves ------------------------------------- */
@@ -594,59 +582,59 @@ void ANIM_flush_setting_anim_channels(bAnimContext *ac, ListBase *anim_data, bAn
/* Delete the given F-Curve from its AnimData block */
void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *fcu)
{
- /* - if no AnimData, we've got nowhere to remove the F-Curve from
- * (this doesn't guarantee that the F-Curve is in there, but at least we tried
- * - if no F-Curve, there is nothing to remove
- */
- if (ELEM(NULL, adt, fcu))
- return;
-
- /* remove from whatever list it came from
- * - Action Group
- * - Action
- * - Drivers
- * - TODO... some others?
- */
- if ((ac) && (ac->datatype == ANIMCONT_DRIVERS)) {
- /* driver F-Curve */
- BLI_remlink(&adt->drivers, fcu);
- }
- else if (adt->action) {
- bAction *act = adt->action;
-
- /* remove from group or action, whichever one "owns" the F-Curve */
- if (fcu->grp) {
- bActionGroup *agrp = fcu->grp;
-
- /* remove F-Curve from group+action */
- action_groups_remove_channel(act, fcu);
-
- /* if group has no more channels, remove it too,
- * otherwise can have many dangling groups [#33541]
- */
- if (BLI_listbase_is_empty(&agrp->channels)) {
- BLI_freelinkN(&act->groups, agrp);
- }
- }
- else {
- BLI_remlink(&act->curves, fcu);
- }
-
- /* if action has no more F-Curves as a result of this, unlink it from
- * AnimData if it did not come from a NLA Strip being tweaked.
- *
- * This is done so that we don't have dangling Object+Action entries in
- * channel list that are empty, and linger around long after the data they
- * are for has disappeared (and probably won't come back).
- */
- if (BLI_listbase_is_empty(&act->curves) && (adt->flag & ADT_NLA_EDIT_ON) == 0) {
- id_us_min(&act->id);
- adt->action = NULL;
- }
- }
-
- /* free the F-Curve itself */
- free_fcurve(fcu);
+ /* - if no AnimData, we've got nowhere to remove the F-Curve from
+ * (this doesn't guarantee that the F-Curve is in there, but at least we tried
+ * - if no F-Curve, there is nothing to remove
+ */
+ if (ELEM(NULL, adt, fcu))
+ return;
+
+ /* remove from whatever list it came from
+ * - Action Group
+ * - Action
+ * - Drivers
+ * - TODO... some others?
+ */
+ if ((ac) && (ac->datatype == ANIMCONT_DRIVERS)) {
+ /* driver F-Curve */
+ BLI_remlink(&adt->drivers, fcu);
+ }
+ else if (adt->action) {
+ bAction *act = adt->action;
+
+ /* remove from group or action, whichever one "owns" the F-Curve */
+ if (fcu->grp) {
+ bActionGroup *agrp = fcu->grp;
+
+ /* remove F-Curve from group+action */
+ action_groups_remove_channel(act, fcu);
+
+ /* if group has no more channels, remove it too,
+ * otherwise can have many dangling groups [#33541]
+ */
+ if (BLI_listbase_is_empty(&agrp->channels)) {
+ BLI_freelinkN(&act->groups, agrp);
+ }
+ }
+ else {
+ BLI_remlink(&act->curves, fcu);
+ }
+
+ /* if action has no more F-Curves as a result of this, unlink it from
+ * AnimData if it did not come from a NLA Strip being tweaked.
+ *
+ * This is done so that we don't have dangling Object+Action entries in
+ * channel list that are empty, and linger around long after the data they
+ * are for has disappeared (and probably won't come back).
+ */
+ if (BLI_listbase_is_empty(&act->curves) && (adt->flag & ADT_NLA_EDIT_ON) == 0) {
+ id_us_min(&act->id);
+ adt->action = NULL;
+ }
+ }
+
+ /* free the F-Curve itself */
+ free_fcurve(fcu);
}
/* ************************************************************************** */
@@ -657,40 +645,40 @@ void ANIM_fcurve_delete_from_animdata(bAnimContext *ac, AnimData *adt, FCurve *f
/* poll callback for being in an Animation Editor channels list region */
static bool animedit_poll_channels_active(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
+ ScrArea *sa = CTX_wm_area(C);
- /* channels region test */
- /* TODO: could enhance with actually testing if channels region? */
- if (ELEM(NULL, sa, CTX_wm_region(C)))
- return 0;
- /* animation editor test */
- if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA) == 0)
- return 0;
+ /* channels region test */
+ /* TODO: could enhance with actually testing if channels region? */
+ if (ELEM(NULL, sa, CTX_wm_region(C)))
+ return 0;
+ /* animation editor test */
+ if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA) == 0)
+ return 0;
- return 1;
+ return 1;
}
/* poll callback for Animation Editor channels list region + not in NLA-tweakmode for NLA */
static bool animedit_poll_channels_nla_tweakmode_off(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
- Scene *scene = CTX_data_scene(C);
+ ScrArea *sa = CTX_wm_area(C);
+ Scene *scene = CTX_data_scene(C);
- /* channels region test */
- /* TODO: could enhance with actually testing if channels region? */
- if (ELEM(NULL, sa, CTX_wm_region(C)))
- return 0;
- /* animation editor test */
- if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA) == 0)
- return 0;
+ /* channels region test */
+ /* TODO: could enhance with actually testing if channels region? */
+ if (ELEM(NULL, sa, CTX_wm_region(C)))
+ return 0;
+ /* animation editor test */
+ if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA) == 0)
+ return 0;
- /* NLA TweakMode test */
- if (sa->spacetype == SPACE_NLA) {
- if ((scene == NULL) || (scene->flag & SCE_NLA_EDIT_ON))
- return 0;
- }
+ /* NLA TweakMode test */
+ if (sa->spacetype == SPACE_NLA) {
+ if ((scene == NULL) || (scene->flag & SCE_NLA_EDIT_ON))
+ return 0;
+ }
- return 1;
+ return 1;
}
/* ****************** Rearrange Channels Operator ******************* */
@@ -698,146 +686,144 @@ static bool animedit_poll_channels_nla_tweakmode_off(bContext *C)
/* constants for channel rearranging */
/* WARNING: don't change existing ones without modifying rearrange func accordingly */
typedef enum eRearrangeAnimChan_Mode {
- REARRANGE_ANIMCHAN_TOP = -2,
- REARRANGE_ANIMCHAN_UP = -1,
- REARRANGE_ANIMCHAN_DOWN = 1,
- REARRANGE_ANIMCHAN_BOTTOM = 2,
+ REARRANGE_ANIMCHAN_TOP = -2,
+ REARRANGE_ANIMCHAN_UP = -1,
+ REARRANGE_ANIMCHAN_DOWN = 1,
+ REARRANGE_ANIMCHAN_BOTTOM = 2,
} eRearrangeAnimChan_Mode;
/* defines for rearranging channels */
static const EnumPropertyItem prop_animchannel_rearrange_types[] = {
- {REARRANGE_ANIMCHAN_TOP, "TOP", 0, "To Top", ""},
- {REARRANGE_ANIMCHAN_UP, "UP", 0, "Up", ""},
- {REARRANGE_ANIMCHAN_DOWN, "DOWN", 0, "Down", ""},
- {REARRANGE_ANIMCHAN_BOTTOM, "BOTTOM", 0, "To Bottom", ""},
- {0, NULL, 0, NULL, NULL},
+ {REARRANGE_ANIMCHAN_TOP, "TOP", 0, "To Top", ""},
+ {REARRANGE_ANIMCHAN_UP, "UP", 0, "Up", ""},
+ {REARRANGE_ANIMCHAN_DOWN, "DOWN", 0, "Down", ""},
+ {REARRANGE_ANIMCHAN_BOTTOM, "BOTTOM", 0, "To Bottom", ""},
+ {0, NULL, 0, NULL, NULL},
};
/* Reordering "Islands" Defines ----------------------------------- */
/* Island definition - just a listbase container */
typedef struct tReorderChannelIsland {
- struct tReorderChannelIsland *next, *prev;
+ struct tReorderChannelIsland *next, *prev;
- ListBase channels; /* channels within this region with the same state */
- int flag; /* eReorderIslandFlag */
+ ListBase channels; /* channels within this region with the same state */
+ int flag; /* eReorderIslandFlag */
} tReorderChannelIsland;
/* flags for channel reordering islands */
typedef enum eReorderIslandFlag {
- REORDER_ISLAND_SELECTED = (1 << 0), /* island is selected */
- REORDER_ISLAND_UNTOUCHABLE = (1 << 1), /* island should be ignored */
- REORDER_ISLAND_MOVED = (1 << 2), /* island has already been moved */
- REORDER_ISLAND_HIDDEN = (1 << 3), /* island is not visible */
+ REORDER_ISLAND_SELECTED = (1 << 0), /* island is selected */
+ REORDER_ISLAND_UNTOUCHABLE = (1 << 1), /* island should be ignored */
+ REORDER_ISLAND_MOVED = (1 << 2), /* island has already been moved */
+ REORDER_ISLAND_HIDDEN = (1 << 3), /* island is not visible */
} eReorderIslandFlag;
-
/* Rearrange Methods --------------------------------------------- */
static bool rearrange_island_ok(tReorderChannelIsland *island)
{
- /* island must not be untouchable */
- if (island->flag & REORDER_ISLAND_UNTOUCHABLE)
- return 0;
+ /* island must not be untouchable */
+ if (island->flag & REORDER_ISLAND_UNTOUCHABLE)
+ return 0;
- /* island should be selected to be moved */
- return (island->flag & REORDER_ISLAND_SELECTED) && !(island->flag & REORDER_ISLAND_MOVED);
+ /* island should be selected to be moved */
+ return (island->flag & REORDER_ISLAND_SELECTED) && !(island->flag & REORDER_ISLAND_MOVED);
}
/* ............................. */
static bool rearrange_island_top(ListBase *list, tReorderChannelIsland *island)
{
- if (rearrange_island_ok(island)) {
- /* remove from current position */
- BLI_remlink(list, island);
+ if (rearrange_island_ok(island)) {
+ /* remove from current position */
+ BLI_remlink(list, island);
- /* make it first element */
- BLI_insertlinkbefore(list, list->first, island);
+ /* make it first element */
+ BLI_insertlinkbefore(list, list->first, island);
- return 1;
- }
+ return 1;
+ }
- return 0;
+ return 0;
}
static bool rearrange_island_up(ListBase *list, tReorderChannelIsland *island)
{
- if (rearrange_island_ok(island)) {
- /* moving up = moving before the previous island, otherwise we're in the same place */
- tReorderChannelIsland *prev = island->prev;
+ if (rearrange_island_ok(island)) {
+ /* moving up = moving before the previous island, otherwise we're in the same place */
+ tReorderChannelIsland *prev = island->prev;
- /* Skip hidden islands! */
- while (prev && prev->flag & REORDER_ISLAND_HIDDEN) {
- prev = prev->prev;
- }
+ /* Skip hidden islands! */
+ while (prev && prev->flag & REORDER_ISLAND_HIDDEN) {
+ prev = prev->prev;
+ }
- if (prev) {
- /* remove from current position */
- BLI_remlink(list, island);
+ if (prev) {
+ /* remove from current position */
+ BLI_remlink(list, island);
- /* push it up */
- BLI_insertlinkbefore(list, prev, island);
+ /* push it up */
+ BLI_insertlinkbefore(list, prev, island);
- return 1;
- }
- }
+ return 1;
+ }
+ }
- return 0;
+ return 0;
}
static bool rearrange_island_down(ListBase *list, tReorderChannelIsland *island)
{
- if (rearrange_island_ok(island)) {
- /* moving down = moving after the next island, otherwise we're in the same place */
- tReorderChannelIsland *next = island->next;
+ if (rearrange_island_ok(island)) {
+ /* moving down = moving after the next island, otherwise we're in the same place */
+ tReorderChannelIsland *next = island->next;
- /* Skip hidden islands! */
- while (next && next->flag & REORDER_ISLAND_HIDDEN) {
- next = next->next;
- }
+ /* Skip hidden islands! */
+ while (next && next->flag & REORDER_ISLAND_HIDDEN) {
+ next = next->next;
+ }
- if (next) {
- /* can only move past if next is not untouchable (i.e. nothing can go after it) */
- if ((next->flag & REORDER_ISLAND_UNTOUCHABLE) == 0) {
- /* remove from current position */
- BLI_remlink(list, island);
+ if (next) {
+ /* can only move past if next is not untouchable (i.e. nothing can go after it) */
+ if ((next->flag & REORDER_ISLAND_UNTOUCHABLE) == 0) {
+ /* remove from current position */
+ BLI_remlink(list, island);
- /* push it down */
- BLI_insertlinkafter(list, next, island);
+ /* push it down */
+ BLI_insertlinkafter(list, next, island);
- return true;
- }
- }
- /* else: no next channel, so we're at the bottom already, so can't move */
- }
+ return true;
+ }
+ }
+ /* else: no next channel, so we're at the bottom already, so can't move */
+ }
- return false;
+ return false;
}
static bool rearrange_island_bottom(ListBase *list, tReorderChannelIsland *island)
{
- if (rearrange_island_ok(island)) {
- tReorderChannelIsland *last = list->last;
-
- /* remove island from current position */
- BLI_remlink(list, island);
+ if (rearrange_island_ok(island)) {
+ tReorderChannelIsland *last = list->last;
- /* add before or after the last channel? */
- if ((last->flag & REORDER_ISLAND_UNTOUCHABLE) == 0) {
- /* can add after it */
- BLI_addtail(list, island);
- }
- else {
- /* can at most go just before it, since last cannot be moved */
- BLI_insertlinkbefore(list, last, island);
+ /* remove island from current position */
+ BLI_remlink(list, island);
- }
+ /* add before or after the last channel? */
+ if ((last->flag & REORDER_ISLAND_UNTOUCHABLE) == 0) {
+ /* can add after it */
+ BLI_addtail(list, island);
+ }
+ else {
+ /* can at most go just before it, since last cannot be moved */
+ BLI_insertlinkbefore(list, last, island);
+ }
- return true;
- }
+ return true;
+ }
- return false;
+ return false;
}
/* ............................. */
@@ -854,184 +840,187 @@ typedef bool (*AnimChanRearrangeFp)(ListBase *list, tReorderChannelIsland *islan
/* get rearranging function, given 'rearrange' mode */
static AnimChanRearrangeFp rearrange_get_mode_func(eRearrangeAnimChan_Mode mode)
{
- switch (mode) {
- case REARRANGE_ANIMCHAN_TOP:
- return rearrange_island_top;
- case REARRANGE_ANIMCHAN_UP:
- return rearrange_island_up;
- case REARRANGE_ANIMCHAN_DOWN:
- return rearrange_island_down;
- case REARRANGE_ANIMCHAN_BOTTOM:
- return rearrange_island_bottom;
- default:
- return NULL;
- }
+ switch (mode) {
+ case REARRANGE_ANIMCHAN_TOP:
+ return rearrange_island_top;
+ case REARRANGE_ANIMCHAN_UP:
+ return rearrange_island_up;
+ case REARRANGE_ANIMCHAN_DOWN:
+ return rearrange_island_down;
+ case REARRANGE_ANIMCHAN_BOTTOM:
+ return rearrange_island_bottom;
+ default:
+ return NULL;
+ }
}
/* Rearrange Islands Generics ------------------------------------- */
/* add channel into list of islands */
-static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *srcList,
- Link *channel, eAnim_ChannelType type,
+static void rearrange_animchannel_add_to_islands(ListBase *islands,
+ ListBase *srcList,
+ Link *channel,
+ eAnim_ChannelType type,
const bool is_hidden)
{
- /* always try to add to last island if possible */
- tReorderChannelIsland *island = islands->last;
- bool is_sel = false, is_untouchable = false;
-
- /* get flags - selected and untouchable from the channel */
- switch (type) {
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = (bActionGroup *)channel;
-
- is_sel = SEL_AGRP(agrp);
- is_untouchable = (agrp->flag & AGRP_TEMP) != 0;
- break;
- }
- case ANIMTYPE_FCURVE:
- case ANIMTYPE_NLACURVE:
- {
- FCurve *fcu = (FCurve *)channel;
-
- is_sel = SEL_FCU(fcu);
- break;
- }
- case ANIMTYPE_NLATRACK:
- {
- NlaTrack *nlt = (NlaTrack *)channel;
-
- is_sel = SEL_NLT(nlt);
- break;
- }
- case ANIMTYPE_GPLAYER:
- {
- bGPDlayer *gpl = (bGPDlayer *)channel;
-
- is_sel = SEL_GPL(gpl);
- break;
- }
- default:
- printf("rearrange_animchannel_add_to_islands(): don't know how to handle channels of type %u\n", type);
- return;
- }
-
- /* do we need to add to a new island? */
- if (/* 1) no islands yet */
- (island == NULL) ||
- /* 2) unselected islands have single channels only - to allow up/down movement */
- ((island->flag & REORDER_ISLAND_SELECTED) == 0) ||
- /* 3) if channel is unselected, stop existing island (it was either wrong sel status, or full already) */
- (is_sel == 0) ||
- /* 4) hidden status changes */
- ((island->flag & REORDER_ISLAND_HIDDEN) != is_hidden)
- )
- {
- /* create a new island now */
- island = MEM_callocN(sizeof(tReorderChannelIsland), "tReorderChannelIsland");
- BLI_addtail(islands, island);
-
- if (is_sel)
- island->flag |= REORDER_ISLAND_SELECTED;
- if (is_untouchable)
- island->flag |= REORDER_ISLAND_UNTOUCHABLE;
- if (is_hidden)
- island->flag |= REORDER_ISLAND_HIDDEN;
- }
-
- /* add channel to island - need to remove it from its existing list first though */
- BLI_remlink(srcList, channel);
- BLI_addtail(&island->channels, channel);
+ /* always try to add to last island if possible */
+ tReorderChannelIsland *island = islands->last;
+ bool is_sel = false, is_untouchable = false;
+
+ /* get flags - selected and untouchable from the channel */
+ switch (type) {
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = (bActionGroup *)channel;
+
+ is_sel = SEL_AGRP(agrp);
+ is_untouchable = (agrp->flag & AGRP_TEMP) != 0;
+ break;
+ }
+ case ANIMTYPE_FCURVE:
+ case ANIMTYPE_NLACURVE: {
+ FCurve *fcu = (FCurve *)channel;
+
+ is_sel = SEL_FCU(fcu);
+ break;
+ }
+ case ANIMTYPE_NLATRACK: {
+ NlaTrack *nlt = (NlaTrack *)channel;
+
+ is_sel = SEL_NLT(nlt);
+ break;
+ }
+ case ANIMTYPE_GPLAYER: {
+ bGPDlayer *gpl = (bGPDlayer *)channel;
+
+ is_sel = SEL_GPL(gpl);
+ break;
+ }
+ default:
+ printf(
+ "rearrange_animchannel_add_to_islands(): don't know how to handle channels of type %u\n",
+ type);
+ return;
+ }
+
+ /* do we need to add to a new island? */
+ if (/* 1) no islands yet */
+ (island == NULL) ||
+ /* 2) unselected islands have single channels only - to allow up/down movement */
+ ((island->flag & REORDER_ISLAND_SELECTED) == 0) ||
+ /* 3) if channel is unselected, stop existing island (it was either wrong sel status, or full already) */
+ (is_sel == 0) ||
+ /* 4) hidden status changes */
+ ((island->flag & REORDER_ISLAND_HIDDEN) != is_hidden)) {
+ /* create a new island now */
+ island = MEM_callocN(sizeof(tReorderChannelIsland), "tReorderChannelIsland");
+ BLI_addtail(islands, island);
+
+ if (is_sel)
+ island->flag |= REORDER_ISLAND_SELECTED;
+ if (is_untouchable)
+ island->flag |= REORDER_ISLAND_UNTOUCHABLE;
+ if (is_hidden)
+ island->flag |= REORDER_ISLAND_HIDDEN;
+ }
+
+ /* add channel to island - need to remove it from its existing list first though */
+ BLI_remlink(srcList, channel);
+ BLI_addtail(&island->channels, channel);
}
/* flatten islands out into a single list again */
static void rearrange_animchannel_flatten_islands(ListBase *islands, ListBase *srcList)
{
- tReorderChannelIsland *island, *isn = NULL;
+ tReorderChannelIsland *island, *isn = NULL;
- /* make sure srcList is empty now */
- BLI_assert(BLI_listbase_is_empty(srcList));
+ /* make sure srcList is empty now */
+ BLI_assert(BLI_listbase_is_empty(srcList));
- /* go through merging islands */
- for (island = islands->first; island; island = isn) {
- isn = island->next;
+ /* go through merging islands */
+ for (island = islands->first; island; island = isn) {
+ isn = island->next;
- /* merge island channels back to main list, then delete the island */
- BLI_movelisttolist(srcList, &island->channels);
- BLI_freelinkN(islands, island);
- }
+ /* merge island channels back to main list, then delete the island */
+ BLI_movelisttolist(srcList, &island->channels);
+ BLI_freelinkN(islands, island);
+ }
}
/* ............................. */
/* get a list of all bAnimListElem's of a certain type which are currently visible */
-static void rearrange_animchannels_filter_visible(ListBase *anim_data_visible, bAnimContext *ac, eAnim_ChannelType type)
+static void rearrange_animchannels_filter_visible(ListBase *anim_data_visible,
+ bAnimContext *ac,
+ eAnim_ChannelType type)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale, *ale_next;
- int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale, *ale_next;
+ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- /* get all visible channels */
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* get all visible channels */
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* now, only keep the ones that are of the types we are interested in */
- for (ale = anim_data.first; ale; ale = ale_next) {
- ale_next = ale->next;
+ /* now, only keep the ones that are of the types we are interested in */
+ for (ale = anim_data.first; ale; ale = ale_next) {
+ ale_next = ale->next;
- if (ale->type != type) {
- BLI_freelinkN(&anim_data, ale);
- }
- }
+ if (ale->type != type) {
+ BLI_freelinkN(&anim_data, ale);
+ }
+ }
- /* return cleaned up list */
- *anim_data_visible = anim_data;
+ /* return cleaned up list */
+ *anim_data_visible = anim_data;
}
/* performing rearranging of channels using islands */
-static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp rearrange_func,
- eRearrangeAnimChan_Mode mode, eAnim_ChannelType type,
+static bool rearrange_animchannel_islands(ListBase *list,
+ AnimChanRearrangeFp rearrange_func,
+ eRearrangeAnimChan_Mode mode,
+ eAnim_ChannelType type,
ListBase *anim_data_visible)
{
- ListBase islands = {NULL, NULL};
- Link *channel, *chanNext = NULL;
- bool done = false;
-
- /* don't waste effort on an empty list */
- if (BLI_listbase_is_empty(list))
- return 0;
-
- /* group channels into islands */
- for (channel = list->first; channel; channel = chanNext) {
- /* find out whether this channel is present in anim_data_visible or not! */
- const bool is_hidden = (BLI_findptr(anim_data_visible, channel, offsetof(bAnimListElem, data)) == NULL);
- chanNext = channel->next;
- rearrange_animchannel_add_to_islands(&islands, list, channel, type, is_hidden);
- }
-
- /* perform moving of selected islands now, but only if there is more than one of 'em so that something will happen
- * - scanning of the list is performed in the opposite direction to the direction we're moving things, so that we
- * shouldn't need to encounter items we've moved already
- */
- if (islands.first != islands.last) {
- tReorderChannelIsland *first = (mode > 0) ? islands.last : islands.first;
- tReorderChannelIsland *island, *isn = NULL;
-
- for (island = first; island; island = isn) {
- isn = (mode > 0) ? island->prev : island->next;
-
- /* perform rearranging */
- if (rearrange_func(&islands, island)) {
- island->flag |= REORDER_ISLAND_MOVED;
- done = true;
- }
- }
- }
-
- /* ungroup islands */
- rearrange_animchannel_flatten_islands(&islands, list);
-
- /* did we do anything? */
- return done;
+ ListBase islands = {NULL, NULL};
+ Link *channel, *chanNext = NULL;
+ bool done = false;
+
+ /* don't waste effort on an empty list */
+ if (BLI_listbase_is_empty(list))
+ return 0;
+
+ /* group channels into islands */
+ for (channel = list->first; channel; channel = chanNext) {
+ /* find out whether this channel is present in anim_data_visible or not! */
+ const bool is_hidden =
+ (BLI_findptr(anim_data_visible, channel, offsetof(bAnimListElem, data)) == NULL);
+ chanNext = channel->next;
+ rearrange_animchannel_add_to_islands(&islands, list, channel, type, is_hidden);
+ }
+
+ /* perform moving of selected islands now, but only if there is more than one of 'em so that something will happen
+ * - scanning of the list is performed in the opposite direction to the direction we're moving things, so that we
+ * shouldn't need to encounter items we've moved already
+ */
+ if (islands.first != islands.last) {
+ tReorderChannelIsland *first = (mode > 0) ? islands.last : islands.first;
+ tReorderChannelIsland *island, *isn = NULL;
+
+ for (island = first; island; island = isn) {
+ isn = (mode > 0) ? island->prev : island->next;
+
+ /* perform rearranging */
+ if (rearrange_func(&islands, island)) {
+ island->flag |= REORDER_ISLAND_MOVED;
+ done = true;
+ }
+ }
+ }
+
+ /* ungroup islands */
+ rearrange_animchannel_flatten_islands(&islands, list);
+
+ /* did we do anything? */
+ return done;
}
/* NLA Specific Stuff ----------------------------------------------------- */
@@ -1042,25 +1031,26 @@ static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp re
*/
static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAnimChan_Mode mode)
{
- AnimChanRearrangeFp rearrange_func;
- ListBase anim_data_visible = {NULL, NULL};
+ AnimChanRearrangeFp rearrange_func;
+ ListBase anim_data_visible = {NULL, NULL};
- /* hack: invert mode so that functions will work in right order */
- mode *= -1;
+ /* hack: invert mode so that functions will work in right order */
+ mode *= -1;
- /* get rearranging function */
- rearrange_func = rearrange_get_mode_func(mode);
- if (rearrange_func == NULL)
- return;
+ /* get rearranging function */
+ rearrange_func = rearrange_get_mode_func(mode);
+ if (rearrange_func == NULL)
+ return;
- /* Filter visible data. */
- rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLATRACK);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLATRACK);
- /* perform rearranging on tracks list */
- rearrange_animchannel_islands(&adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK, &anim_data_visible);
+ /* perform rearranging on tracks list */
+ rearrange_animchannel_islands(
+ &adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK, &anim_data_visible);
- /* free temp data */
- BLI_freelistN(&anim_data_visible);
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
}
/* Drivers Specific Stuff ------------------------------------------------- */
@@ -1068,27 +1058,30 @@ static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, eRearrangeAn
/* Change the order drivers within AnimData block
* mode: REARRANGE_ANIMCHAN_*
*/
-static void rearrange_driver_channels(bAnimContext *ac, AnimData *adt, eRearrangeAnimChan_Mode mode)
+static void rearrange_driver_channels(bAnimContext *ac,
+ AnimData *adt,
+ eRearrangeAnimChan_Mode mode)
{
- /* get rearranging function */
- AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
- ListBase anim_data_visible = {NULL, NULL};
+ /* get rearranging function */
+ AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
+ ListBase anim_data_visible = {NULL, NULL};
- if (rearrange_func == NULL)
- return;
+ if (rearrange_func == NULL)
+ return;
- /* only consider drivers if they're accessible */
- if (EXPANDED_DRVD(adt) == 0)
- return;
+ /* only consider drivers if they're accessible */
+ if (EXPANDED_DRVD(adt) == 0)
+ return;
- /* Filter visible data. */
- rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
- /* perform rearranging on drivers list (drivers are really just F-Curves) */
- rearrange_animchannel_islands(&adt->drivers, rearrange_func, mode, ANIMTYPE_FCURVE, &anim_data_visible);
+ /* perform rearranging on drivers list (drivers are really just F-Curves) */
+ rearrange_animchannel_islands(
+ &adt->drivers, rearrange_func, mode, ANIMTYPE_FCURVE, &anim_data_visible);
- /* free temp data */
- BLI_freelistN(&anim_data_visible);
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
}
/* Action Specific Stuff ------------------------------------------------- */
@@ -1096,88 +1089,88 @@ static void rearrange_driver_channels(bAnimContext *ac, AnimData *adt, eRearrang
/* make sure all action-channels belong to a group (and clear action's list) */
static void split_groups_action_temp(bAction *act, bActionGroup *tgrp)
{
- bActionGroup *agrp;
- FCurve *fcu;
-
- if (act == NULL)
- return;
-
- /* Separate F-Curves into lists per group */
- for (agrp = act->groups.first; agrp; agrp = agrp->next) {
- if (agrp->channels.first) {
- fcu = agrp->channels.last;
- act->curves.first = fcu->next;
-
- fcu = agrp->channels.first;
- fcu->prev = NULL;
-
- fcu = agrp->channels.last;
- fcu->next = NULL;
- }
- }
-
- /* Initialize memory for temp-group */
- memset(tgrp, 0, sizeof(bActionGroup));
- tgrp->flag |= (AGRP_EXPANDED | AGRP_TEMP);
- BLI_strncpy(tgrp->name, "#TempGroup", sizeof(tgrp->name));
-
- /* Move any action-channels not already moved, to the temp group */
- if (act->curves.first) {
- /* start of list */
- fcu = act->curves.first;
- fcu->prev = NULL;
- tgrp->channels.first = fcu;
- act->curves.first = NULL;
-
- /* end of list */
- fcu = act->curves.last;
- fcu->next = NULL;
- tgrp->channels.last = fcu;
- act->curves.last = NULL;
-
- /* ensure that all of these get their group set to this temp group
- * (so that visibility filtering works)
- */
- for (fcu = tgrp->channels.first; fcu; fcu = fcu->next) {
- fcu->grp = tgrp;
- }
- }
-
- /* Add temp-group to list */
- BLI_addtail(&act->groups, tgrp);
+ bActionGroup *agrp;
+ FCurve *fcu;
+
+ if (act == NULL)
+ return;
+
+ /* Separate F-Curves into lists per group */
+ for (agrp = act->groups.first; agrp; agrp = agrp->next) {
+ if (agrp->channels.first) {
+ fcu = agrp->channels.last;
+ act->curves.first = fcu->next;
+
+ fcu = agrp->channels.first;
+ fcu->prev = NULL;
+
+ fcu = agrp->channels.last;
+ fcu->next = NULL;
+ }
+ }
+
+ /* Initialize memory for temp-group */
+ memset(tgrp, 0, sizeof(bActionGroup));
+ tgrp->flag |= (AGRP_EXPANDED | AGRP_TEMP);
+ BLI_strncpy(tgrp->name, "#TempGroup", sizeof(tgrp->name));
+
+ /* Move any action-channels not already moved, to the temp group */
+ if (act->curves.first) {
+ /* start of list */
+ fcu = act->curves.first;
+ fcu->prev = NULL;
+ tgrp->channels.first = fcu;
+ act->curves.first = NULL;
+
+ /* end of list */
+ fcu = act->curves.last;
+ fcu->next = NULL;
+ tgrp->channels.last = fcu;
+ act->curves.last = NULL;
+
+ /* ensure that all of these get their group set to this temp group
+ * (so that visibility filtering works)
+ */
+ for (fcu = tgrp->channels.first; fcu; fcu = fcu->next) {
+ fcu->grp = tgrp;
+ }
+ }
+
+ /* Add temp-group to list */
+ BLI_addtail(&act->groups, tgrp);
}
/* link lists of channels that groups have */
static void join_groups_action_temp(bAction *act)
{
- bActionGroup *agrp;
+ bActionGroup *agrp;
- for (agrp = act->groups.first; agrp; agrp = agrp->next) {
- ListBase tempGroup;
+ for (agrp = act->groups.first; agrp; agrp = agrp->next) {
+ ListBase tempGroup;
- /* add list of channels to action's channels */
- tempGroup = agrp->channels;
- BLI_movelisttolist(&act->curves, &agrp->channels);
- agrp->channels = tempGroup;
+ /* add list of channels to action's channels */
+ tempGroup = agrp->channels;
+ BLI_movelisttolist(&act->curves, &agrp->channels);
+ agrp->channels = tempGroup;
- /* clear moved flag */
- agrp->flag &= ~AGRP_MOVED;
+ /* clear moved flag */
+ agrp->flag &= ~AGRP_MOVED;
- /* if group was temporary one:
- * - unassign all FCurves which were temporarily added to it
- * - remove from list (but don't free as it's on the stack!)
- */
- if (agrp->flag & AGRP_TEMP) {
- FCurve *fcu;
+ /* if group was temporary one:
+ * - unassign all FCurves which were temporarily added to it
+ * - remove from list (but don't free as it's on the stack!)
+ */
+ if (agrp->flag & AGRP_TEMP) {
+ FCurve *fcu;
- for (fcu = agrp->channels.first; fcu; fcu = fcu->next) {
- fcu->grp = NULL;
- }
+ for (fcu = agrp->channels.first; fcu; fcu = fcu->next) {
+ fcu->grp = NULL;
+ }
- BLI_remlink(&act->groups, agrp);
- break;
- }
- }
+ BLI_remlink(&act->groups, agrp);
+ break;
+ }
+ }
}
/* Change the order of anim-channels within action
@@ -1185,635 +1178,644 @@ static void join_groups_action_temp(bAction *act)
*/
static void rearrange_action_channels(bAnimContext *ac, bAction *act, eRearrangeAnimChan_Mode mode)
{
- bActionGroup tgrp;
- ListBase anim_data_visible = {NULL, NULL};
- bool do_channels;
+ bActionGroup tgrp;
+ ListBase anim_data_visible = {NULL, NULL};
+ bool do_channels;
- /* get rearranging function */
- AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
+ /* get rearranging function */
+ AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
- if (rearrange_func == NULL)
- return;
+ if (rearrange_func == NULL)
+ return;
- /* make sure we're only operating with groups (vs a mixture of groups+curves) */
- split_groups_action_temp(act, &tgrp);
+ /* make sure we're only operating with groups (vs a mixture of groups+curves) */
+ split_groups_action_temp(act, &tgrp);
- /* Filter visible data. */
- rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GROUP);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GROUP);
- /* rearrange groups first
- * - the group's channels will only get considered if nothing happened when rearranging the groups
- * i.e. the rearrange function returned 0
- */
- do_channels = (rearrange_animchannel_islands(&act->groups, rearrange_func, mode, ANIMTYPE_GROUP,
- &anim_data_visible) == 0);
+ /* rearrange groups first
+ * - the group's channels will only get considered if nothing happened when rearranging the groups
+ * i.e. the rearrange function returned 0
+ */
+ do_channels = (rearrange_animchannel_islands(
+ &act->groups, rearrange_func, mode, ANIMTYPE_GROUP, &anim_data_visible) == 0);
- /* free temp data */
- BLI_freelistN(&anim_data_visible);
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
- if (do_channels) {
- bActionGroup *agrp;
+ if (do_channels) {
+ bActionGroup *agrp;
- /* Filter visible data. */
- rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
- for (agrp = act->groups.first; agrp; agrp = agrp->next) {
- /* only consider F-Curves if they're visible (group expanded) */
- if (EXPANDED_AGRP(ac, agrp)) {
- rearrange_animchannel_islands(&agrp->channels, rearrange_func, mode, ANIMTYPE_FCURVE,
- &anim_data_visible);
- }
- }
+ for (agrp = act->groups.first; agrp; agrp = agrp->next) {
+ /* only consider F-Curves if they're visible (group expanded) */
+ if (EXPANDED_AGRP(ac, agrp)) {
+ rearrange_animchannel_islands(
+ &agrp->channels, rearrange_func, mode, ANIMTYPE_FCURVE, &anim_data_visible);
+ }
+ }
- /* free temp data */
- BLI_freelistN(&anim_data_visible);
- }
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
+ }
- /* assemble lists into one list (and clear moved tags) */
- join_groups_action_temp(act);
+ /* assemble lists into one list (and clear moved tags) */
+ join_groups_action_temp(act);
}
/* ------------------- */
-static void rearrange_nla_control_channels(bAnimContext *ac, AnimData *adt, eRearrangeAnimChan_Mode mode)
+static void rearrange_nla_control_channels(bAnimContext *ac,
+ AnimData *adt,
+ eRearrangeAnimChan_Mode mode)
{
- ListBase anim_data_visible = {NULL, NULL};
+ ListBase anim_data_visible = {NULL, NULL};
- NlaTrack *nlt;
- NlaStrip *strip;
+ NlaTrack *nlt;
+ NlaStrip *strip;
- /* get rearranging function */
- AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
+ /* get rearranging function */
+ AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
- if (rearrange_func == NULL)
- return;
+ if (rearrange_func == NULL)
+ return;
- /* skip if these curves aren't being shown */
- if (adt->flag & ADT_NLA_SKEYS_COLLAPSED)
- return;
+ /* skip if these curves aren't being shown */
+ if (adt->flag & ADT_NLA_SKEYS_COLLAPSED)
+ return;
- /* Filter visible data. */
- rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLACURVE);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLACURVE);
- /* we cannot rearrange between strips, but within each strip, we can rearrange those curves */
- for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
- for (strip = nlt->strips.first; strip; strip = strip->next) {
- rearrange_animchannel_islands(
- &strip->fcurves, rearrange_func, mode, ANIMTYPE_NLACURVE,
- &anim_data_visible);
- }
- }
+ /* we cannot rearrange between strips, but within each strip, we can rearrange those curves */
+ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+ for (strip = nlt->strips.first; strip; strip = strip->next) {
+ rearrange_animchannel_islands(
+ &strip->fcurves, rearrange_func, mode, ANIMTYPE_NLACURVE, &anim_data_visible);
+ }
+ }
- /* free temp data */
- BLI_freelistN(&anim_data_visible);
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
}
/* ------------------- */
static void rearrange_gpencil_channels(bAnimContext *ac, eRearrangeAnimChan_Mode mode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* get rearranging function */
- AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
+ /* get rearranging function */
+ AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
- if (rearrange_func == NULL)
- return;
+ if (rearrange_func == NULL)
+ return;
- /* get Grease Pencil datablocks */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* get Grease Pencil datablocks */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- ListBase anim_data_visible = {NULL, NULL};
- bGPdata *gpd = ale->data;
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ ListBase anim_data_visible = {NULL, NULL};
+ bGPdata *gpd = ale->data;
- /* only consider layers if this datablock is open */
- BLI_assert(ale->type == ANIMTYPE_GPDATABLOCK);
- if ((gpd->flag & GP_DATA_EXPAND) == 0)
- continue;
+ /* only consider layers if this datablock is open */
+ BLI_assert(ale->type == ANIMTYPE_GPDATABLOCK);
+ if ((gpd->flag & GP_DATA_EXPAND) == 0)
+ continue;
- /* Filter visible data. */
- rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GPLAYER);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GPLAYER);
- /* rearrange datablock's layers */
- rearrange_animchannel_islands(&gpd->layers, rearrange_func, mode, ANIMTYPE_GPLAYER, &anim_data_visible);
+ /* rearrange datablock's layers */
+ rearrange_animchannel_islands(
+ &gpd->layers, rearrange_func, mode, ANIMTYPE_GPLAYER, &anim_data_visible);
- /* free visible layers data */
- BLI_freelistN(&anim_data_visible);
- }
+ /* free visible layers data */
+ BLI_freelistN(&anim_data_visible);
+ }
- /* free GPD channel data */
- ANIM_animdata_freelist(&anim_data);
+ /* free GPD channel data */
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int animchannels_rearrange_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- eRearrangeAnimChan_Mode mode;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get mode */
- mode = RNA_enum_get(op->ptr, "direction");
-
- /* method to move channels depends on the editor */
- if (ac.datatype == ANIMCONT_GPENCIL) {
- /* Grease Pencil channels */
- rearrange_gpencil_channels(&ac, mode);
- }
- else if (ac.datatype == ANIMCONT_MASK) {
- /* Grease Pencil channels */
- printf("Mask does not supported for moving yet\n");
- }
- else if (ac.datatype == ANIMCONT_ACTION) {
- /* Directly rearrange action's channels */
- rearrange_action_channels(&ac, ac.data, mode);
- }
- else {
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* get animdata blocks */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- AnimData *adt = ale->data;
-
- switch (ac.datatype) {
- case ANIMCONT_NLA: /* NLA-tracks only */
- rearrange_nla_channels(&ac, adt, mode);
- DEG_id_tag_update(ale->id, ID_RECALC_ANIMATION);
- break;
-
- case ANIMCONT_DRIVERS: /* Drivers list only */
- rearrange_driver_channels(&ac, adt, mode);
- break;
-
- case ANIMCONT_ACTION: /* Single Action only... */
- case ANIMCONT_SHAPEKEY: // DOUBLE CHECK ME...
- {
- if (adt->action)
- rearrange_action_channels(&ac, adt->action, mode);
- else if (G.debug & G_DEBUG)
- printf("Animdata has no action\n");
- break;
- }
-
- default: /* DopeSheet/Graph Editor - Some Actions + NLA Control Curves */
- {
- /* NLA Control Curves */
- if (adt->nla_tracks.first)
- rearrange_nla_control_channels(&ac, adt, mode);
-
- /* Action */
- if (adt->action)
- rearrange_action_channels(&ac, adt->action, mode);
- else if (G.debug & G_DEBUG)
- printf("Animdata has no action\n");
- break;
- }
- }
- }
-
- /* free temp data */
- ANIM_animdata_freelist(&anim_data);
- }
-
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ eRearrangeAnimChan_Mode mode;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get mode */
+ mode = RNA_enum_get(op->ptr, "direction");
+
+ /* method to move channels depends on the editor */
+ if (ac.datatype == ANIMCONT_GPENCIL) {
+ /* Grease Pencil channels */
+ rearrange_gpencil_channels(&ac, mode);
+ }
+ else if (ac.datatype == ANIMCONT_MASK) {
+ /* Grease Pencil channels */
+ printf("Mask does not supported for moving yet\n");
+ }
+ else if (ac.datatype == ANIMCONT_ACTION) {
+ /* Directly rearrange action's channels */
+ rearrange_action_channels(&ac, ac.data, mode);
+ }
+ else {
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get animdata blocks */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ AnimData *adt = ale->data;
+
+ switch (ac.datatype) {
+ case ANIMCONT_NLA: /* NLA-tracks only */
+ rearrange_nla_channels(&ac, adt, mode);
+ DEG_id_tag_update(ale->id, ID_RECALC_ANIMATION);
+ break;
+
+ case ANIMCONT_DRIVERS: /* Drivers list only */
+ rearrange_driver_channels(&ac, adt, mode);
+ break;
+
+ case ANIMCONT_ACTION: /* Single Action only... */
+ case ANIMCONT_SHAPEKEY: // DOUBLE CHECK ME...
+ {
+ if (adt->action)
+ rearrange_action_channels(&ac, adt->action, mode);
+ else if (G.debug & G_DEBUG)
+ printf("Animdata has no action\n");
+ break;
+ }
+
+ default: /* DopeSheet/Graph Editor - Some Actions + NLA Control Curves */
+ {
+ /* NLA Control Curves */
+ if (adt->nla_tracks.first)
+ rearrange_nla_control_channels(&ac, adt, mode);
+
+ /* Action */
+ if (adt->action)
+ rearrange_action_channels(&ac, adt->action, mode);
+ else if (G.debug & G_DEBUG)
+ printf("Animdata has no action\n");
+ break;
+ }
+ }
+ }
+
+ /* free temp data */
+ ANIM_animdata_freelist(&anim_data);
+ }
+
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_move(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Move Channels";
- ot->idname = "ANIM_OT_channels_move";
- ot->description = "Rearrange selected animation channels";
+ /* identifiers */
+ ot->name = "Move Channels";
+ ot->idname = "ANIM_OT_channels_move";
+ ot->description = "Rearrange selected animation channels";
- /* api callbacks */
- ot->exec = animchannels_rearrange_exec;
- ot->poll = animedit_poll_channels_nla_tweakmode_off;
+ /* api callbacks */
+ ot->exec = animchannels_rearrange_exec;
+ ot->poll = animedit_poll_channels_nla_tweakmode_off;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- ot->prop = RNA_def_enum(ot->srna, "direction", prop_animchannel_rearrange_types, REARRANGE_ANIMCHAN_DOWN, "Direction", "");
+ /* props */
+ ot->prop = RNA_def_enum(ot->srna,
+ "direction",
+ prop_animchannel_rearrange_types,
+ REARRANGE_ANIMCHAN_DOWN,
+ "Direction",
+ "");
}
/* ******************** Group Channel Operator ************************ */
static bool animchannels_grouping_poll(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
- SpaceLink *sl;
+ ScrArea *sa = CTX_wm_area(C);
+ SpaceLink *sl;
- /* channels region test */
- /* TODO: could enhance with actually testing if channels region? */
- if (ELEM(NULL, sa, CTX_wm_region(C)))
- return 0;
+ /* channels region test */
+ /* TODO: could enhance with actually testing if channels region? */
+ if (ELEM(NULL, sa, CTX_wm_region(C)))
+ return 0;
- /* animation editor test - must be suitable modes only */
- sl = CTX_wm_space_data(C);
+ /* animation editor test - must be suitable modes only */
+ sl = CTX_wm_space_data(C);
- switch (sa->spacetype) {
- /* supported... */
- case SPACE_ACTION:
- {
- SpaceAction *saction = (SpaceAction *)sl;
+ switch (sa->spacetype) {
+ /* supported... */
+ case SPACE_ACTION: {
+ SpaceAction *saction = (SpaceAction *)sl;
- /* dopesheet and action only - all others are for other datatypes or have no groups */
- if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_DOPESHEET) == 0)
- return 0;
+ /* dopesheet and action only - all others are for other datatypes or have no groups */
+ if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_DOPESHEET) == 0)
+ return 0;
- break;
- }
- case SPACE_GRAPH:
- {
- SpaceGraph *sipo = (SpaceGraph *)sl;
+ break;
+ }
+ case SPACE_GRAPH: {
+ SpaceGraph *sipo = (SpaceGraph *)sl;
- /* drivers can't have groups... */
- if (sipo->mode != SIPO_MODE_ANIMATION)
- return 0;
+ /* drivers can't have groups... */
+ if (sipo->mode != SIPO_MODE_ANIMATION)
+ return 0;
- break;
- }
- /* unsupported... */
- default:
- return 0;
- }
+ break;
+ }
+ /* unsupported... */
+ default:
+ return 0;
+ }
- return 1;
+ return 1;
}
/* ----------------------------------------------------------- */
-static void animchannels_group_channels(bAnimContext *ac, bAnimListElem *adt_ref, const char name[])
+static void animchannels_group_channels(bAnimContext *ac,
+ bAnimListElem *adt_ref,
+ const char name[])
{
- AnimData *adt = adt_ref->adt;
- bAction *act = adt->action;
+ AnimData *adt = adt_ref->adt;
+ bAction *act = adt->action;
- if (act) {
- ListBase anim_data = {NULL, NULL};
- int filter;
+ if (act) {
+ ListBase anim_data = {NULL, NULL};
+ int filter;
- /* find selected F-Curves to re-group */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL);
- ANIM_animdata_filter(ac, &anim_data, filter, adt_ref, ANIMCONT_CHANNEL);
+ /* find selected F-Curves to re-group */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL);
+ ANIM_animdata_filter(ac, &anim_data, filter, adt_ref, ANIMCONT_CHANNEL);
- if (anim_data.first) {
- bActionGroup *agrp;
- bAnimListElem *ale;
+ if (anim_data.first) {
+ bActionGroup *agrp;
+ bAnimListElem *ale;
- /* create new group, which should now be part of the action */
- agrp = action_groups_add_new(act, name);
- BLI_assert(agrp != NULL);
+ /* create new group, which should now be part of the action */
+ agrp = action_groups_add_new(act, name);
+ BLI_assert(agrp != NULL);
- /* transfer selected F-Curves across to new group */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->data;
- bActionGroup *grp = fcu->grp;
+ /* transfer selected F-Curves across to new group */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
+ bActionGroup *grp = fcu->grp;
- /* remove F-Curve from group, then group too if it is now empty */
- action_groups_remove_channel(act, fcu);
+ /* remove F-Curve from group, then group too if it is now empty */
+ action_groups_remove_channel(act, fcu);
- if ((grp) && BLI_listbase_is_empty(&grp->channels)) {
- BLI_freelinkN(&act->groups, grp);
- }
+ if ((grp) && BLI_listbase_is_empty(&grp->channels)) {
+ BLI_freelinkN(&act->groups, grp);
+ }
- /* add F-Curve to group */
- action_groups_add_channel(act, agrp, fcu);
- }
- }
+ /* add F-Curve to group */
+ action_groups_add_channel(act, agrp, fcu);
+ }
+ }
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
- }
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
+ }
}
static int animchannels_group_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- char name[MAX_NAME];
+ bAnimContext ac;
+ char name[MAX_NAME];
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get name for new group */
- RNA_string_get(op->ptr, "name", name);
+ /* get name for new group */
+ RNA_string_get(op->ptr, "name", name);
- /* XXX: name for group should never be empty... */
- if (name[0]) {
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ /* XXX: name for group should never be empty... */
+ if (name[0]) {
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* handle each animdata block separately, so that the regrouping doesn't flow into blocks */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* handle each animdata block separately, so that the regrouping doesn't flow into blocks */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- animchannels_group_channels(&ac, ale, name);
- }
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ animchannels_group_channels(&ac, ale, name);
+ }
- /* free temp data */
- ANIM_animdata_freelist(&anim_data);
+ /* free temp data */
+ ANIM_animdata_freelist(&anim_data);
- /* updatss */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- }
+ /* updatss */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ }
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_group(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Group Channels";
- ot->idname = "ANIM_OT_channels_group";
- ot->description = "Add selected F-Curves to a new group";
+ /* identifiers */
+ ot->name = "Group Channels";
+ ot->idname = "ANIM_OT_channels_group";
+ ot->description = "Add selected F-Curves to a new group";
- /* callbacks */
- ot->invoke = WM_operator_props_popup;
- ot->exec = animchannels_group_exec;
- ot->poll = animchannels_grouping_poll;
+ /* callbacks */
+ ot->invoke = WM_operator_props_popup;
+ ot->exec = animchannels_group_exec;
+ ot->poll = animchannels_grouping_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- ot->prop = RNA_def_string(ot->srna, "name", "New Group",
- sizeof(((bActionGroup *)NULL)->name),
- "Name", "Name of newly created group");
- /* XXX: still not too sure about this - keeping same text is confusing... */
- // RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
+ /* props */
+ ot->prop = RNA_def_string(ot->srna,
+ "name",
+ "New Group",
+ sizeof(((bActionGroup *)NULL)->name),
+ "Name",
+ "Name of newly created group");
+ /* XXX: still not too sure about this - keeping same text is confusing... */
+ // RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE);
}
/* ----------------------------------------------------------- */
static int animchannels_ungroup_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* just selected F-Curves... */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* just selected F-Curves... */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL |
+ ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* find action for this F-Curve... */
- if (ale->adt && ale->adt->action) {
- FCurve *fcu = (FCurve *)ale->data;
- bAction *act = ale->adt->action;
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* find action for this F-Curve... */
+ if (ale->adt && ale->adt->action) {
+ FCurve *fcu = (FCurve *)ale->data;
+ bAction *act = ale->adt->action;
- /* only proceed to remove if F-Curve is in a group... */
- if (fcu->grp) {
- bActionGroup *agrp = fcu->grp;
+ /* only proceed to remove if F-Curve is in a group... */
+ if (fcu->grp) {
+ bActionGroup *agrp = fcu->grp;
- /* remove F-Curve from group and add at tail (ungrouped) */
- action_groups_remove_channel(act, fcu);
- BLI_addtail(&act->curves, fcu);
+ /* remove F-Curve from group and add at tail (ungrouped) */
+ action_groups_remove_channel(act, fcu);
+ BLI_addtail(&act->curves, fcu);
- /* delete group if it is now empty */
- if (BLI_listbase_is_empty(&agrp->channels)) {
- BLI_freelinkN(&act->groups, agrp);
- }
- }
- }
- }
+ /* delete group if it is now empty */
+ if (BLI_listbase_is_empty(&agrp->channels)) {
+ BLI_freelinkN(&act->groups, agrp);
+ }
+ }
+ }
+ }
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
- /* updates */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* updates */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_ungroup(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Ungroup Channels";
- ot->idname = "ANIM_OT_channels_ungroup";
- ot->description = "Remove selected F-Curves from their current groups";
+ /* identifiers */
+ ot->name = "Ungroup Channels";
+ ot->idname = "ANIM_OT_channels_ungroup";
+ ot->description = "Remove selected F-Curves from their current groups";
- /* callbacks */
- ot->exec = animchannels_ungroup_exec;
- ot->poll = animchannels_grouping_poll;
+ /* callbacks */
+ ot->exec = animchannels_ungroup_exec;
+ ot->poll = animchannels_grouping_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Delete Channel Operator *********************** */
static void update_dependencies_on_delete(bAnimListElem *ale)
{
- ID *id = ale->id;
- AnimData *adt = BKE_animdata_from_id(id);
- /* TODO(sergey): Technically, if the animation element is being deleted
- * from a driver we don't have to tag action. This is something we can check
- * for in the future. For now just do most reliable tag whic hwas always
- * happening. */
- if (adt != NULL) {
- DEG_id_tag_update(id, ID_RECALC_ANIMATION);
- if (adt->action != NULL) {
- DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION);
- }
- }
- /* Deals with NLA and drivers.
- * Doesn't cause overhead for action updates, since object will receive
- * animation update after dependency graph flushes update from action to
- * all its users. */
- DEG_id_tag_update(id, ID_RECALC_ANIMATION);
+ ID *id = ale->id;
+ AnimData *adt = BKE_animdata_from_id(id);
+ /* TODO(sergey): Technically, if the animation element is being deleted
+ * from a driver we don't have to tag action. This is something we can check
+ * for in the future. For now just do most reliable tag whic hwas always
+ * happening. */
+ if (adt != NULL) {
+ DEG_id_tag_update(id, ID_RECALC_ANIMATION);
+ if (adt->action != NULL) {
+ DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION);
+ }
+ }
+ /* Deals with NLA and drivers.
+ * Doesn't cause overhead for action updates, since object will receive
+ * animation update after dependency graph flushes update from action to
+ * all its users. */
+ DEG_id_tag_update(id, ID_RECALC_ANIMATION);
}
static int animchannels_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* cannot delete in shapekey */
- if (ac.datatype == ANIMCONT_SHAPEKEY)
- return OPERATOR_CANCELLED;
-
-
- /* do groups only first (unless in Drivers mode, where there are none) */
- if (ac.datatype != ANIMCONT_DRIVERS) {
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- /* delete selected groups and their associated channels */
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* only groups - don't check other types yet, since they may no-longer exist */
- if (ale->type == ANIMTYPE_GROUP) {
- bActionGroup *agrp = (bActionGroup *)ale->data;
- AnimData *adt = ale->adt;
- FCurve *fcu, *fcn;
-
- /* skip this group if no AnimData available, as we can't safely remove the F-Curves */
- if (adt == NULL)
- continue;
-
- /* delete all of the Group's F-Curves, but no others */
- for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcn) {
- fcn = fcu->next;
-
- /* remove from group and action, then free */
- action_groups_remove_channel(adt->action, fcu);
- free_fcurve(fcu);
- }
-
- /* free the group itself */
- if (adt->action) {
- BLI_freelinkN(&adt->action->groups, agrp);
- DEG_id_tag_update_ex(CTX_data_main(C), &adt->action->id, ID_RECALC_ANIMATION);
- }
- else
- MEM_freeN(agrp);
- }
- }
-
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
- }
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- /* delete selected data channels */
- for (ale = anim_data.first; ale; ale = ale->next) {
- switch (ale->type) {
- case ANIMTYPE_FCURVE:
- {
- /* F-Curves if we can identify its parent */
- AnimData *adt = ale->adt;
- FCurve *fcu = (FCurve *)ale->data;
-
- /* try to free F-Curve */
- ANIM_fcurve_delete_from_animdata(&ac, adt, fcu);
- update_dependencies_on_delete(ale);
- break;
- }
- case ANIMTYPE_NLACURVE:
- {
- /* NLA Control Curve - Deleting it should disable the corresponding setting... */
- NlaStrip *strip = (NlaStrip *)ale->owner;
- FCurve *fcu = (FCurve *)ale->data;
-
- if (STREQ(fcu->rna_path, "strip_time")) {
- strip->flag &= ~NLASTRIP_FLAG_USR_TIME;
- }
- else if (STREQ(fcu->rna_path, "influence")) {
- strip->flag &= ~NLASTRIP_FLAG_USR_INFLUENCE;
- }
- else {
- printf("ERROR: Trying to delete NLA Control Curve for unknown property '%s'\n", fcu->rna_path);
- }
-
- /* unlink and free the F-Curve */
- BLI_remlink(&strip->fcurves, fcu);
- free_fcurve(fcu);
- update_dependencies_on_delete(ale);
- break;
- }
- case ANIMTYPE_GPLAYER:
- {
- /* Grease Pencil layer */
- bGPdata *gpd = (bGPdata *)ale->id;
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
- /* try to delete the layer's data and the layer itself */
- BKE_gpencil_layer_delete(gpd, gpl);
- ale->update = ANIM_UPDATE_DEPS;
- break;
- }
- case ANIMTYPE_MASKLAYER:
- {
- /* Mask layer */
- Mask *mask = (Mask *)ale->id;
- MaskLayer *masklay = (MaskLayer *)ale->data;
-
- /* try to delete the layer's data and the layer itself */
- BKE_mask_layer_remove(mask, masklay);
- break;
- }
- }
- }
-
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
-
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- DEG_relations_tag_update(CTX_data_main(C));
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* cannot delete in shapekey */
+ if (ac.datatype == ANIMCONT_SHAPEKEY)
+ return OPERATOR_CANCELLED;
+
+ /* do groups only first (unless in Drivers mode, where there are none) */
+ if (ac.datatype != ANIMCONT_DRIVERS) {
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL |
+ ANIMFILTER_LIST_CHANNELS | ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* delete selected groups and their associated channels */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* only groups - don't check other types yet, since they may no-longer exist */
+ if (ale->type == ANIMTYPE_GROUP) {
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+ AnimData *adt = ale->adt;
+ FCurve *fcu, *fcn;
+
+ /* skip this group if no AnimData available, as we can't safely remove the F-Curves */
+ if (adt == NULL)
+ continue;
+
+ /* delete all of the Group's F-Curves, but no others */
+ for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcn) {
+ fcn = fcu->next;
+
+ /* remove from group and action, then free */
+ action_groups_remove_channel(adt->action, fcu);
+ free_fcurve(fcu);
+ }
+
+ /* free the group itself */
+ if (adt->action) {
+ BLI_freelinkN(&adt->action->groups, agrp);
+ DEG_id_tag_update_ex(CTX_data_main(C), &adt->action->id, ID_RECALC_ANIMATION);
+ }
+ else
+ MEM_freeN(agrp);
+ }
+ }
+
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
+ }
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_SEL |
+ ANIMFILTER_FOREDIT | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* delete selected data channels */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ switch (ale->type) {
+ case ANIMTYPE_FCURVE: {
+ /* F-Curves if we can identify its parent */
+ AnimData *adt = ale->adt;
+ FCurve *fcu = (FCurve *)ale->data;
+
+ /* try to free F-Curve */
+ ANIM_fcurve_delete_from_animdata(&ac, adt, fcu);
+ update_dependencies_on_delete(ale);
+ break;
+ }
+ case ANIMTYPE_NLACURVE: {
+ /* NLA Control Curve - Deleting it should disable the corresponding setting... */
+ NlaStrip *strip = (NlaStrip *)ale->owner;
+ FCurve *fcu = (FCurve *)ale->data;
+
+ if (STREQ(fcu->rna_path, "strip_time")) {
+ strip->flag &= ~NLASTRIP_FLAG_USR_TIME;
+ }
+ else if (STREQ(fcu->rna_path, "influence")) {
+ strip->flag &= ~NLASTRIP_FLAG_USR_INFLUENCE;
+ }
+ else {
+ printf("ERROR: Trying to delete NLA Control Curve for unknown property '%s'\n",
+ fcu->rna_path);
+ }
+
+ /* unlink and free the F-Curve */
+ BLI_remlink(&strip->fcurves, fcu);
+ free_fcurve(fcu);
+ update_dependencies_on_delete(ale);
+ break;
+ }
+ case ANIMTYPE_GPLAYER: {
+ /* Grease Pencil layer */
+ bGPdata *gpd = (bGPdata *)ale->id;
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ /* try to delete the layer's data and the layer itself */
+ BKE_gpencil_layer_delete(gpd, gpl);
+ ale->update = ANIM_UPDATE_DEPS;
+ break;
+ }
+ case ANIMTYPE_MASKLAYER: {
+ /* Mask layer */
+ Mask *mask = (Mask *)ale->id;
+ MaskLayer *masklay = (MaskLayer *)ale->data;
+
+ /* try to delete the layer's data and the layer itself */
+ BKE_mask_layer_remove(mask, masklay);
+ break;
+ }
+ }
+ }
+
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
+
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ DEG_relations_tag_update(CTX_data_main(C));
+
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_delete(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Delete Channels";
- ot->idname = "ANIM_OT_channels_delete";
- ot->description = "Delete all selected animation channels";
+ /* identifiers */
+ ot->name = "Delete Channels";
+ ot->idname = "ANIM_OT_channels_delete";
+ ot->description = "Delete all selected animation channels";
- /* api callbacks */
- ot->exec = animchannels_delete_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->exec = animchannels_delete_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ********************** Set Flags Operator *********************** */
/* defines for setting animation-channel flags */
static const EnumPropertyItem prop_animchannel_setflag_types[] = {
- {ACHANNEL_SETFLAG_TOGGLE, "TOGGLE", 0, "Toggle", ""},
- {ACHANNEL_SETFLAG_CLEAR, "DISABLE", 0, "Disable", ""},
- {ACHANNEL_SETFLAG_ADD, "ENABLE", 0, "Enable", ""},
- {ACHANNEL_SETFLAG_INVERT, "INVERT", 0, "Invert", ""},
- {0, NULL, 0, NULL, NULL},
+ {ACHANNEL_SETFLAG_TOGGLE, "TOGGLE", 0, "Toggle", ""},
+ {ACHANNEL_SETFLAG_CLEAR, "DISABLE", 0, "Disable", ""},
+ {ACHANNEL_SETFLAG_ADD, "ENABLE", 0, "Enable", ""},
+ {ACHANNEL_SETFLAG_INVERT, "INVERT", 0, "Invert", ""},
+ {0, NULL, 0, NULL, NULL},
};
/* defines for set animation-channel settings */
// TODO: could add some more types, but those are really quite dependent on the mode...
static const EnumPropertyItem prop_animchannel_settings_types[] = {
- {ACHANNEL_SETTING_PROTECT, "PROTECT", 0, "Protect", ""},
- {ACHANNEL_SETTING_MUTE, "MUTE", 0, "Mute", ""},
- {0, NULL, 0, NULL, NULL},
+ {ACHANNEL_SETTING_PROTECT, "PROTECT", 0, "Protect", ""},
+ {ACHANNEL_SETTING_MUTE, "MUTE", 0, "Mute", ""},
+ {0, NULL, 0, NULL, NULL},
};
-
/* ------------------- */
/* Set/clear a particular flag (setting) for all selected + visible channels
@@ -1822,288 +1824,302 @@ static const EnumPropertyItem prop_animchannel_settings_types[] = {
* onlysel: only selected channels get the flag set
*/
// TODO: enable a setting which turns flushing on/off?
-static void setflag_anim_channels(bAnimContext *ac, eAnimChannel_Settings setting, eAnimChannels_SetFlag mode, bool onlysel, bool flush)
-{
- ListBase anim_data = {NULL, NULL};
- ListBase all_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* filter data that we need if flush is on */
- if (flush) {
- /* get list of all channels that selection may need to be flushed to
- * - hierarchy visibility needs to be ignored so that settings can get flushed
- * "down" inside closed containers
- */
- filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
- ANIM_animdata_filter(ac, &all_data, filter, ac->data, ac->datatype);
- }
-
- /* filter data that we're working on
- * - hierarchy matters if we're doing this from the channels region
- * since we only want to apply this to channels we can "see",
- * and have these affect their relatives
- * - but for Graph Editor, this gets used also from main region
- * where hierarchy doesn't apply [#21276]
- */
- if ((ac->spacetype == SPACE_GRAPH) && (ac->regiontype != RGN_TYPE_CHANNELS)) {
- /* graph editor (case 2) */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- }
- else {
- /* standard case */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS);
- }
- if (onlysel) filter |= ANIMFILTER_SEL;
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* if toggling, check if disable or enable */
- if (mode == ACHANNEL_SETFLAG_TOGGLE) {
- /* default to turn all on, unless we encounter one that's on... */
- mode = ACHANNEL_SETFLAG_ADD;
-
- /* see if we should turn off instead... */
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* set the setting in the appropriate way (if available) */
- if (ANIM_channel_setting_get(ac, ale, setting) > 0) {
- mode = ACHANNEL_SETFLAG_CLEAR;
- break;
- }
- }
- }
-
- /* apply the setting */
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* skip channel if setting is not available */
- if (ANIM_channel_setting_get(ac, ale, setting) == -1)
- continue;
-
- /* set the setting in the appropriate way */
- ANIM_channel_setting_set(ac, ale, setting, mode);
-
- /* if flush status... */
- if (flush)
- ANIM_flush_setting_anim_channels(ac, &all_data, ale, setting, mode);
- }
-
- ANIM_animdata_freelist(&anim_data);
- BLI_freelistN(&all_data);
+static void setflag_anim_channels(bAnimContext *ac,
+ eAnimChannel_Settings setting,
+ eAnimChannels_SetFlag mode,
+ bool onlysel,
+ bool flush)
+{
+ ListBase anim_data = {NULL, NULL};
+ ListBase all_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* filter data that we need if flush is on */
+ if (flush) {
+ /* get list of all channels that selection may need to be flushed to
+ * - hierarchy visibility needs to be ignored so that settings can get flushed
+ * "down" inside closed containers
+ */
+ filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS;
+ ANIM_animdata_filter(ac, &all_data, filter, ac->data, ac->datatype);
+ }
+
+ /* filter data that we're working on
+ * - hierarchy matters if we're doing this from the channels region
+ * since we only want to apply this to channels we can "see",
+ * and have these affect their relatives
+ * - but for Graph Editor, this gets used also from main region
+ * where hierarchy doesn't apply [#21276]
+ */
+ if ((ac->spacetype == SPACE_GRAPH) && (ac->regiontype != RGN_TYPE_CHANNELS)) {
+ /* graph editor (case 2) */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_CURVE_VISIBLE |
+ ANIMFILTER_NODUPLIS);
+ }
+ else {
+ /* standard case */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS |
+ ANIMFILTER_NODUPLIS);
+ }
+ if (onlysel)
+ filter |= ANIMFILTER_SEL;
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* if toggling, check if disable or enable */
+ if (mode == ACHANNEL_SETFLAG_TOGGLE) {
+ /* default to turn all on, unless we encounter one that's on... */
+ mode = ACHANNEL_SETFLAG_ADD;
+
+ /* see if we should turn off instead... */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* set the setting in the appropriate way (if available) */
+ if (ANIM_channel_setting_get(ac, ale, setting) > 0) {
+ mode = ACHANNEL_SETFLAG_CLEAR;
+ break;
+ }
+ }
+ }
+
+ /* apply the setting */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* skip channel if setting is not available */
+ if (ANIM_channel_setting_get(ac, ale, setting) == -1)
+ continue;
+
+ /* set the setting in the appropriate way */
+ ANIM_channel_setting_set(ac, ale, setting, mode);
+
+ /* if flush status... */
+ if (flush)
+ ANIM_flush_setting_anim_channels(ac, &all_data, ale, setting, mode);
+ }
+
+ ANIM_animdata_freelist(&anim_data);
+ BLI_freelistN(&all_data);
}
/* ------------------- */
static int animchannels_setflag_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- eAnimChannel_Settings setting;
- eAnimChannels_SetFlag mode;
- bool flush = true;
+ bAnimContext ac;
+ eAnimChannel_Settings setting;
+ eAnimChannels_SetFlag mode;
+ bool flush = true;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* mode (eAnimChannels_SetFlag), setting (eAnimChannel_Settings) */
- mode = RNA_enum_get(op->ptr, "mode");
- setting = RNA_enum_get(op->ptr, "type");
+ /* mode (eAnimChannels_SetFlag), setting (eAnimChannel_Settings) */
+ mode = RNA_enum_get(op->ptr, "mode");
+ setting = RNA_enum_get(op->ptr, "type");
- /* check if setting is flushable */
- if (setting == ACHANNEL_SETTING_EXPAND)
- flush = false;
+ /* check if setting is flushable */
+ if (setting == ACHANNEL_SETTING_EXPAND)
+ flush = false;
- /* modify setting
- * - only selected channels are affected
- */
- setflag_anim_channels(&ac, setting, mode, true, flush);
+ /* modify setting
+ * - only selected channels are affected
+ */
+ setflag_anim_channels(&ac, setting, mode, true, flush);
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
/* duplicate of 'ANIM_OT_channels_setting_toggle' for menu title only, weak! */
static void ANIM_OT_channels_setting_enable(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Enable Channel Setting";
- ot->idname = "ANIM_OT_channels_setting_enable";
- ot->description = "Enable specified setting on all selected animation channels";
+ /* identifiers */
+ ot->name = "Enable Channel Setting";
+ ot->idname = "ANIM_OT_channels_setting_enable";
+ ot->description = "Enable specified setting on all selected animation channels";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = animchannels_setflag_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = animchannels_setflag_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- /* flag-setting mode */
- prop = RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_ADD, "Mode", "");
- RNA_def_property_flag(prop, PROP_HIDDEN);
- /* setting to set */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
+ /* props */
+ /* flag-setting mode */
+ prop = RNA_def_enum(
+ ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_ADD, "Mode", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ /* setting to set */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
}
/* duplicate of 'ANIM_OT_channels_setting_toggle' for menu title only, weak! */
static void ANIM_OT_channels_setting_disable(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Disable Channel Setting";
- ot->idname = "ANIM_OT_channels_setting_disable";
- ot->description = "Disable specified setting on all selected animation channels";
+ /* identifiers */
+ ot->name = "Disable Channel Setting";
+ ot->idname = "ANIM_OT_channels_setting_disable";
+ ot->description = "Disable specified setting on all selected animation channels";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = animchannels_setflag_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = animchannels_setflag_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- /* flag-setting mode */
- prop = RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_CLEAR, "Mode", "");
- RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
- /* setting to set */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
+ /* props */
+ /* flag-setting mode */
+ prop = RNA_def_enum(
+ ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_CLEAR, "Mode", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
+ /* setting to set */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
}
static void ANIM_OT_channels_setting_toggle(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Toggle Channel Setting";
- ot->idname = "ANIM_OT_channels_setting_toggle";
- ot->description = "Toggle specified setting on all selected animation channels";
+ /* identifiers */
+ ot->name = "Toggle Channel Setting";
+ ot->idname = "ANIM_OT_channels_setting_toggle";
+ ot->description = "Toggle specified setting on all selected animation channels";
- /* api callbacks */
- ot->invoke = WM_menu_invoke;
- ot->exec = animchannels_setflag_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->invoke = WM_menu_invoke;
+ ot->exec = animchannels_setflag_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- /* flag-setting mode */
- prop = RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
- RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
- /* setting to set */
- ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
+ /* props */
+ /* flag-setting mode */
+ prop = RNA_def_enum(
+ ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
+ /* setting to set */
+ ot->prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, 0, "Type", "");
}
static void ANIM_OT_channels_editable_toggle(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Toggle Channel Editability";
- ot->idname = "ANIM_OT_channels_editable_toggle";
- ot->description = "Toggle editability of selected channels";
+ /* identifiers */
+ ot->name = "Toggle Channel Editability";
+ ot->idname = "ANIM_OT_channels_editable_toggle";
+ ot->description = "Toggle editability of selected channels";
- /* api callbacks */
- ot->exec = animchannels_setflag_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->exec = animchannels_setflag_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- /* flag-setting mode */
- RNA_def_enum(ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
- /* setting to set */
- prop = RNA_def_enum(ot->srna, "type", prop_animchannel_settings_types, ACHANNEL_SETTING_PROTECT, "Type", "");
- RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
+ /* props */
+ /* flag-setting mode */
+ RNA_def_enum(
+ ot->srna, "mode", prop_animchannel_setflag_types, ACHANNEL_SETFLAG_TOGGLE, "Mode", "");
+ /* setting to set */
+ prop = RNA_def_enum(
+ ot->srna, "type", prop_animchannel_settings_types, ACHANNEL_SETTING_PROTECT, "Type", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN); /* internal hack - don't expose */
}
/* ********************** Expand Channels Operator *********************** */
static int animchannels_expand_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- bool onlysel = true;
+ bAnimContext ac;
+ bool onlysel = true;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* only affect selected channels? */
- if (RNA_boolean_get(op->ptr, "all"))
- onlysel = false;
+ /* only affect selected channels? */
+ if (RNA_boolean_get(op->ptr, "all"))
+ onlysel = false;
- /* modify setting */
- setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_ADD, onlysel, false);
+ /* modify setting */
+ setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_ADD, onlysel, false);
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_expand(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Expand Channels";
- ot->idname = "ANIM_OT_channels_expand";
- ot->description = "Expand (i.e. open) all selected expandable animation channels";
+ /* identifiers */
+ ot->name = "Expand Channels";
+ ot->idname = "ANIM_OT_channels_expand";
+ ot->description = "Expand (i.e. open) all selected expandable animation channels";
- /* api callbacks */
- ot->exec = animchannels_expand_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->exec = animchannels_expand_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- ot->prop = RNA_def_boolean(ot->srna, "all", 1, "All", "Expand all channels (not just selected ones)");
+ /* props */
+ ot->prop = RNA_def_boolean(
+ ot->srna, "all", 1, "All", "Expand all channels (not just selected ones)");
}
/* ********************** Collapse Channels Operator *********************** */
static int animchannels_collapse_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- bool onlysel = true;
+ bAnimContext ac;
+ bool onlysel = true;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* only affect selected channels? */
- if (RNA_boolean_get(op->ptr, "all"))
- onlysel = false;
+ /* only affect selected channels? */
+ if (RNA_boolean_get(op->ptr, "all"))
+ onlysel = false;
- /* modify setting */
- setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_CLEAR, onlysel, false);
+ /* modify setting */
+ setflag_anim_channels(&ac, ACHANNEL_SETTING_EXPAND, ACHANNEL_SETFLAG_CLEAR, onlysel, false);
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_collapse(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Collapse Channels";
- ot->idname = "ANIM_OT_channels_collapse";
- ot->description = "Collapse (i.e. close) all selected expandable animation channels";
+ /* identifiers */
+ ot->name = "Collapse Channels";
+ ot->idname = "ANIM_OT_channels_collapse";
+ ot->description = "Collapse (i.e. close) all selected expandable animation channels";
- /* api callbacks */
- ot->exec = animchannels_collapse_exec;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->exec = animchannels_collapse_exec;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* props */
- ot->prop = RNA_def_boolean(ot->srna, "all", true, "All", "Collapse all channels (not just selected ones)");
+ /* props */
+ ot->prop = RNA_def_boolean(
+ ot->srna, "all", true, "All", "Collapse all channels (not just selected ones)");
}
/* ************ Remove All "Empty" AnimData Blocks Operator ********* */
@@ -2120,170 +2136,169 @@ static void ANIM_OT_channels_collapse(wmOperatorType *ot)
static int animchannels_clean_empty_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
-
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get animdata blocks */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- for (ale = anim_data.first; ale; ale = ale->next) {
- ID *id = ale->id;
- AnimData *adt = ale->data;
-
- bool action_empty = false;
- bool nla_empty = false;
- bool drivers_empty = false;
-
- /* sanity checks */
- BLI_assert((id != NULL) && (adt != NULL));
-
- /* check if this is "empty" and can be deleted */
- /* (For now, there are only these 3 criteria) */
-
- /* 1) Active Action is missing or empty */
- if (ELEM(NULL, adt->action, adt->action->curves.first)) {
- action_empty = true;
- }
- else {
- /* TODO: check for keyframe + fmodifier data on these too */
- }
-
- /* 2) No NLA Tracks and/or NLA Strips */
- if (adt->nla_tracks.first == NULL) {
- nla_empty = true;
- }
- else {
- NlaTrack *nlt;
-
- /* empty tracks? */
- for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
- if (nlt->strips.first) {
- /* stop searching, as we found one that actually had stuff we don't want lost
- * NOTE: nla_empty gets reset to false, as a previous track may have been empty
- */
- nla_empty = false;
- break;
- }
- else if (nlt->strips.first == NULL) {
- /* this track is empty, but another one may still have stuff in it, so can't break yet */
- nla_empty = true;
- }
- }
- }
-
- /* 3) Drivers */
- drivers_empty = (adt->drivers.first == NULL);
-
-
- /* remove AnimData? */
- if (action_empty && nla_empty && drivers_empty) {
- BKE_animdata_free(id, true);
- }
- }
-
- /* free temp data */
- ANIM_animdata_freelist(&anim_data);
-
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get animdata blocks */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_ANIMDATA);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ ID *id = ale->id;
+ AnimData *adt = ale->data;
+
+ bool action_empty = false;
+ bool nla_empty = false;
+ bool drivers_empty = false;
+
+ /* sanity checks */
+ BLI_assert((id != NULL) && (adt != NULL));
+
+ /* check if this is "empty" and can be deleted */
+ /* (For now, there are only these 3 criteria) */
+
+ /* 1) Active Action is missing or empty */
+ if (ELEM(NULL, adt->action, adt->action->curves.first)) {
+ action_empty = true;
+ }
+ else {
+ /* TODO: check for keyframe + fmodifier data on these too */
+ }
+
+ /* 2) No NLA Tracks and/or NLA Strips */
+ if (adt->nla_tracks.first == NULL) {
+ nla_empty = true;
+ }
+ else {
+ NlaTrack *nlt;
+
+ /* empty tracks? */
+ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+ if (nlt->strips.first) {
+ /* stop searching, as we found one that actually had stuff we don't want lost
+ * NOTE: nla_empty gets reset to false, as a previous track may have been empty
+ */
+ nla_empty = false;
+ break;
+ }
+ else if (nlt->strips.first == NULL) {
+ /* this track is empty, but another one may still have stuff in it, so can't break yet */
+ nla_empty = true;
+ }
+ }
+ }
+
+ /* 3) Drivers */
+ drivers_empty = (adt->drivers.first == NULL);
+
+ /* remove AnimData? */
+ if (action_empty && nla_empty && drivers_empty) {
+ BKE_animdata_free(id, true);
+ }
+ }
+
+ /* free temp data */
+ ANIM_animdata_freelist(&anim_data);
+
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_clean_empty(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Empty Animation Data";
- ot->idname = "ANIM_OT_channels_clean_empty";
- ot->description = "Delete all empty animation data containers from visible data-blocks";
+ /* identifiers */
+ ot->name = "Remove Empty Animation Data";
+ ot->idname = "ANIM_OT_channels_clean_empty";
+ ot->description = "Delete all empty animation data containers from visible data-blocks";
- /* api callbacks */
- ot->exec = animchannels_clean_empty_exec;
- ot->poll = animedit_poll_channels_nla_tweakmode_off;
+ /* api callbacks */
+ ot->exec = animchannels_clean_empty_exec;
+ ot->poll = animedit_poll_channels_nla_tweakmode_off;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************* Reenable Disabled Operator ******************* */
static bool animchannels_enable_poll(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
+ ScrArea *sa = CTX_wm_area(C);
- /* channels region test */
- /* TODO: could enhance with actually testing if channels region? */
- if (ELEM(NULL, sa, CTX_wm_region(C)))
- return 0;
+ /* channels region test */
+ /* TODO: could enhance with actually testing if channels region? */
+ if (ELEM(NULL, sa, CTX_wm_region(C)))
+ return 0;
- /* animation editor test - Action/Dopesheet/etc. and Graph only */
- if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH) == 0)
- return 0;
+ /* animation editor test - Action/Dopesheet/etc. and Graph only */
+ if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH) == 0)
+ return 0;
- return 1;
+ return 1;
}
static int animchannels_enable_exec(bContext *C, wmOperator *UNUSED(op))
{
- bAnimContext ac;
+ bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS);
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- /* loop through filtered data and clean curves */
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->data;
+ /* loop through filtered data and clean curves */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->data;
- /* remove disabled flags from F-Curves */
- fcu->flag &= ~FCURVE_DISABLED;
+ /* remove disabled flags from F-Curves */
+ fcu->flag &= ~FCURVE_DISABLED;
- /* for drivers, let's do the same too */
- if (fcu->driver)
- fcu->driver->flag &= ~DRIVER_FLAG_INVALID;
+ /* for drivers, let's do the same too */
+ if (fcu->driver)
+ fcu->driver->flag &= ~DRIVER_FLAG_INVALID;
- /* tag everything for updates - in particular, this is needed to get drivers working again */
- ale->update |= ANIM_UPDATE_DEPS;
- }
+ /* tag everything for updates - in particular, this is needed to get drivers working again */
+ ale->update |= ANIM_UPDATE_DEPS;
+ }
- ANIM_animdata_update(&ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_update(&ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_fcurves_enable(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Revive Disabled F-Curves";
- ot->idname = "ANIM_OT_channels_fcurves_enable";
- ot->description = "Clears 'disabled' tag from all F-Curves to get broken F-Curves working again";
+ /* identifiers */
+ ot->name = "Revive Disabled F-Curves";
+ ot->idname = "ANIM_OT_channels_fcurves_enable";
+ ot->description = "Clears 'disabled' tag from all F-Curves to get broken F-Curves working again";
- /* api callbacks */
- ot->exec = animchannels_enable_exec;
- ot->poll = animchannels_enable_poll;
+ /* api callbacks */
+ ot->exec = animchannels_enable_exec;
+ ot->poll = animchannels_enable_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ****************** Find / Set Filter Operator ******************** */
@@ -2291,253 +2306,256 @@ static void ANIM_OT_channels_fcurves_enable(wmOperatorType *ot)
/* XXX: make this generic? */
static bool animchannels_find_poll(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
+ ScrArea *sa = CTX_wm_area(C);
- if (sa == NULL)
- return 0;
+ if (sa == NULL)
+ return 0;
- /* animation editor with dopesheet */
- return ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA);
+ /* animation editor with dopesheet */
+ return ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA);
}
/* find_invoke() - Get initial channels */
static int animchannels_find_invoke(bContext *C, wmOperator *op, const wmEvent *evt)
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* set initial filter text, and enable filter */
- RNA_string_set(op->ptr, "query", ac.ads->searchstr);
+ /* set initial filter text, and enable filter */
+ RNA_string_set(op->ptr, "query", ac.ads->searchstr);
- /* defer to popup */
- return WM_operator_props_popup(C, op, evt);
+ /* defer to popup */
+ return WM_operator_props_popup(C, op, evt);
}
/* find_exec() - Called to set the value */
static int animchannels_find_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
+ bAnimContext ac;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* update filter text */
- RNA_string_get(op->ptr, "query", ac.ads->searchstr);
+ /* update filter text */
+ RNA_string_get(op->ptr, "query", ac.ads->searchstr);
- /* redraw */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
+ /* redraw */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_find(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Find Channels";
- ot->idname = "ANIM_OT_channels_find";
- ot->description = "Filter the set of channels shown to only include those with matching names";
+ /* identifiers */
+ ot->name = "Find Channels";
+ ot->idname = "ANIM_OT_channels_find";
+ ot->description = "Filter the set of channels shown to only include those with matching names";
- /* callbacks */
- ot->invoke = animchannels_find_invoke;
- ot->exec = animchannels_find_exec;
- ot->poll = animchannels_find_poll;
+ /* callbacks */
+ ot->invoke = animchannels_find_invoke;
+ ot->exec = animchannels_find_exec;
+ ot->poll = animchannels_find_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- ot->prop = RNA_def_string(ot->srna, "query", "Query", sizeof(((bDopeSheet *)NULL)->searchstr), "", "Text to search for in channel names");
+ /* properties */
+ ot->prop = RNA_def_string(ot->srna,
+ "query",
+ "Query",
+ sizeof(((bDopeSheet *)NULL)->searchstr),
+ "",
+ "Text to search for in channel names");
}
/* ********************** Select All Operator *********************** */
static int animchannels_deselectall_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* 'standard' behavior - check if selected, then apply relevant selection */
- const int action = RNA_enum_get(op->ptr, "action");
- switch (action) {
- case SEL_TOGGLE:
- ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, true, ACHANNEL_SETFLAG_ADD);
- break;
- case SEL_SELECT:
- ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_ADD);
- break;
- case SEL_DESELECT:
- ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_CLEAR);
- break;
- case SEL_INVERT:
- ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_INVERT);
- break;
- default:
- BLI_assert(0);
- break;
- }
-
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* 'standard' behavior - check if selected, then apply relevant selection */
+ const int action = RNA_enum_get(op->ptr, "action");
+ switch (action) {
+ case SEL_TOGGLE:
+ ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, true, ACHANNEL_SETFLAG_ADD);
+ break;
+ case SEL_SELECT:
+ ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_ADD);
+ break;
+ case SEL_DESELECT:
+ ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ break;
+ case SEL_INVERT:
+ ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, false, ACHANNEL_SETFLAG_INVERT);
+ break;
+ default:
+ BLI_assert(0);
+ break;
+ }
+
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
+
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_select_all(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Select All";
- ot->idname = "ANIM_OT_channels_select_all";
- ot->description = "Toggle selection of all animation channels";
+ /* identifiers */
+ ot->name = "Select All";
+ ot->idname = "ANIM_OT_channels_select_all";
+ ot->description = "Toggle selection of all animation channels";
- /* api callbacks */
- ot->exec = animchannels_deselectall_exec;
- ot->poll = animedit_poll_channels_nla_tweakmode_off;
+ /* api callbacks */
+ ot->exec = animchannels_deselectall_exec;
+ ot->poll = animedit_poll_channels_nla_tweakmode_off;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- WM_operator_properties_select_all(ot);
+ /* properties */
+ WM_operator_properties_select_all(ot);
}
/* ******************** Box Select Operator *********************** */
static void box_select_anim_channels(bAnimContext *ac, rcti *rect, short selectmode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- SpaceNla *snla = (SpaceNla *)ac->sl;
- View2D *v2d = &ac->ar->v2d;
- rctf rectf;
- float ymin, ymax;
-
- /* set initial y extents */
- if (ac->datatype == ANIMCONT_NLA) {
- ymin = (float)(-NLACHANNEL_HEIGHT(snla));
- ymax = 0.0f;
- }
- else {
- ymin = 0.0f;
- ymax = (float)(-ACHANNEL_HEIGHT(ac));
- }
-
- /* convert border-region to view coordinates */
- UI_view2d_region_to_view(v2d, rect->xmin, rect->ymin + 2, &rectf.xmin, &rectf.ymin);
- UI_view2d_region_to_view(v2d, rect->xmax, rect->ymax - 2, &rectf.xmax, &rectf.ymax);
-
- /* filter data */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop over data, doing box select */
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ac->datatype == ANIMCONT_NLA)
- ymin = ymax - NLACHANNEL_STEP(snla);
- else
- ymin = ymax - ACHANNEL_STEP(ac);
-
- /* if channel is within border-select region, alter it */
- if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
- /* set selection flags only */
- ANIM_channel_setting_set(ac, ale, ACHANNEL_SETTING_SELECT, selectmode);
-
- /* type specific actions */
- switch (ale->type) {
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = (bActionGroup *)ale->data;
- select_pchan_for_action_group(ac, agrp, ale);
- /* always clear active flag after doing this */
- agrp->flag &= ~AGRP_ACTIVE;
- break;
- }
- case ANIMTYPE_NLATRACK:
- {
- NlaTrack *nlt = (NlaTrack *)ale->data;
-
- /* for now, it's easier just to do this here manually, as defining a new type
- * currently adds complications when doing other stuff
- */
- ACHANNEL_SET_FLAG(nlt, selectmode, NLATRACK_SELECTED);
- break;
- }
- }
- }
-
- /* set minimum extent to be the maximum of the next channel */
- ymax = ymin;
- }
-
- /* cleanup */
- ANIM_animdata_freelist(&anim_data);
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ SpaceNla *snla = (SpaceNla *)ac->sl;
+ View2D *v2d = &ac->ar->v2d;
+ rctf rectf;
+ float ymin, ymax;
+
+ /* set initial y extents */
+ if (ac->datatype == ANIMCONT_NLA) {
+ ymin = (float)(-NLACHANNEL_HEIGHT(snla));
+ ymax = 0.0f;
+ }
+ else {
+ ymin = 0.0f;
+ ymax = (float)(-ACHANNEL_HEIGHT(ac));
+ }
+
+ /* convert border-region to view coordinates */
+ UI_view2d_region_to_view(v2d, rect->xmin, rect->ymin + 2, &rectf.xmin, &rectf.ymin);
+ UI_view2d_region_to_view(v2d, rect->xmax, rect->ymax - 2, &rectf.xmax, &rectf.ymax);
+
+ /* filter data */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop over data, doing box select */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (ac->datatype == ANIMCONT_NLA)
+ ymin = ymax - NLACHANNEL_STEP(snla);
+ else
+ ymin = ymax - ACHANNEL_STEP(ac);
+
+ /* if channel is within border-select region, alter it */
+ if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
+ /* set selection flags only */
+ ANIM_channel_setting_set(ac, ale, ACHANNEL_SETTING_SELECT, selectmode);
+
+ /* type specific actions */
+ switch (ale->type) {
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+ select_pchan_for_action_group(ac, agrp, ale);
+ /* always clear active flag after doing this */
+ agrp->flag &= ~AGRP_ACTIVE;
+ break;
+ }
+ case ANIMTYPE_NLATRACK: {
+ NlaTrack *nlt = (NlaTrack *)ale->data;
+
+ /* for now, it's easier just to do this here manually, as defining a new type
+ * currently adds complications when doing other stuff
+ */
+ ACHANNEL_SET_FLAG(nlt, selectmode, NLATRACK_SELECTED);
+ break;
+ }
+ }
+ }
+
+ /* set minimum extent to be the maximum of the next channel */
+ ymax = ymin;
+ }
+
+ /* cleanup */
+ ANIM_animdata_freelist(&anim_data);
}
/* ------------------- */
static int animchannels_box_select_exec(bContext *C, wmOperator *op)
{
- bAnimContext ac;
- rcti rect;
- short selectmode = 0;
- const bool select = !RNA_boolean_get(op->ptr, "deselect");
- const bool extend = RNA_boolean_get(op->ptr, "extend");
+ bAnimContext ac;
+ rcti rect;
+ short selectmode = 0;
+ const bool select = !RNA_boolean_get(op->ptr, "deselect");
+ const bool extend = RNA_boolean_get(op->ptr, "extend");
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- /* get settings from operator */
- WM_operator_properties_border_to_rcti(op, &rect);
+ /* get settings from operator */
+ WM_operator_properties_border_to_rcti(op, &rect);
- if (!extend) {
- ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, true, ACHANNEL_SETFLAG_CLEAR);
- }
+ if (!extend) {
+ ANIM_deselect_anim_channels(&ac, ac.data, ac.datatype, true, ACHANNEL_SETFLAG_CLEAR);
+ }
- if (select) {
- selectmode = ACHANNEL_SETFLAG_ADD;
- }
- else {
- selectmode = ACHANNEL_SETFLAG_CLEAR;
- }
+ if (select) {
+ selectmode = ACHANNEL_SETFLAG_ADD;
+ }
+ else {
+ selectmode = ACHANNEL_SETFLAG_CLEAR;
+ }
- /* apply box_select animation channels */
- box_select_anim_channels(&ac, &rect, selectmode);
+ /* apply box_select animation channels */
+ box_select_anim_channels(&ac, &rect, selectmode);
- /* send notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
+ /* send notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_select_box(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Box Select";
- ot->idname = "ANIM_OT_channels_select_box";
- ot->description = "Select all animation channels within the specified region";
+ /* identifiers */
+ ot->name = "Box Select";
+ ot->idname = "ANIM_OT_channels_select_box";
+ ot->description = "Select all animation channels within the specified region";
- /* api callbacks */
- ot->invoke = WM_gesture_box_invoke;
- ot->exec = animchannels_box_select_exec;
- ot->modal = WM_gesture_box_modal;
- ot->cancel = WM_gesture_box_cancel;
+ /* api callbacks */
+ ot->invoke = WM_gesture_box_invoke;
+ ot->exec = animchannels_box_select_exec;
+ ot->modal = WM_gesture_box_modal;
+ ot->cancel = WM_gesture_box_cancel;
- ot->poll = animedit_poll_channels_nla_tweakmode_off;
+ ot->poll = animedit_poll_channels_nla_tweakmode_off;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* rna */
- WM_operator_properties_gesture_box_select(ot);
+ /* rna */
+ WM_operator_properties_gesture_box_select(ot);
}
/* ******************* Rename Operator ***************************** */
@@ -2545,114 +2563,131 @@ static void ANIM_OT_channels_select_box(wmOperatorType *ot)
static bool rename_anim_channels(bAnimContext *ac, int channel_index)
{
- ListBase anim_data = {NULL, NULL};
- const bAnimChannelType *acf;
- bAnimListElem *ale;
- int filter;
- bool success = false;
-
- /* get the channel that was clicked on */
- /* filter channels */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* get channel from index */
- ale = BLI_findlink(&anim_data, channel_index);
- if (ale == NULL) {
- /* channel not found */
- if (G.debug & G_DEBUG)
- printf("Error: animation channel (index = %d) not found in rename_anim_channels()\n", channel_index);
-
- ANIM_animdata_freelist(&anim_data);
- return false;
- }
-
- /* check that channel can be renamed */
- acf = ANIM_channel_get_typeinfo(ale);
- if (acf && acf->name_prop) {
- PointerRNA ptr;
- PropertyRNA *prop;
-
- /* ok if we can get name property to edit from this channel */
- if (acf->name_prop(ale, &ptr, &prop)) {
- /* actually showing the rename textfield is done on redraw,
- * so here we just store the index of this channel in the
- * dopesheet data, which will get utilized when drawing the
- * channel...
- *
- * +1 factor is for backwards compat issues
- */
- if (ac->ads) {
- ac->ads->renameIndex = channel_index + 1;
- success = true;
- }
- }
- }
-
- /* free temp data and tag for refresh */
- ANIM_animdata_freelist(&anim_data);
- ED_region_tag_redraw(ac->ar);
- return success;
+ ListBase anim_data = {NULL, NULL};
+ const bAnimChannelType *acf;
+ bAnimListElem *ale;
+ int filter;
+ bool success = false;
+
+ /* get the channel that was clicked on */
+ /* filter channels */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* get channel from index */
+ ale = BLI_findlink(&anim_data, channel_index);
+ if (ale == NULL) {
+ /* channel not found */
+ if (G.debug & G_DEBUG)
+ printf("Error: animation channel (index = %d) not found in rename_anim_channels()\n",
+ channel_index);
+
+ ANIM_animdata_freelist(&anim_data);
+ return false;
+ }
+
+ /* check that channel can be renamed */
+ acf = ANIM_channel_get_typeinfo(ale);
+ if (acf && acf->name_prop) {
+ PointerRNA ptr;
+ PropertyRNA *prop;
+
+ /* ok if we can get name property to edit from this channel */
+ if (acf->name_prop(ale, &ptr, &prop)) {
+ /* actually showing the rename textfield is done on redraw,
+ * so here we just store the index of this channel in the
+ * dopesheet data, which will get utilized when drawing the
+ * channel...
+ *
+ * +1 factor is for backwards compat issues
+ */
+ if (ac->ads) {
+ ac->ads->renameIndex = channel_index + 1;
+ success = true;
+ }
+ }
+ }
+
+ /* free temp data and tag for refresh */
+ ANIM_animdata_freelist(&anim_data);
+ ED_region_tag_redraw(ac->ar);
+ return success;
}
static int animchannels_channel_get(bAnimContext *ac, const int mval[2])
{
- ARegion *ar;
- View2D *v2d;
- int channel_index;
- float x, y;
-
- /* get useful pointers from animation context data */
- ar = ac->ar;
- v2d = &ar->v2d;
-
- /* figure out which channel user clicked in
- * Note: although channels technically start at (y = ACHANNEL_FIRST), we need to adjust by half a channel's height
- * so that the tops of channels get caught ok. Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use
- * ACHANNEL_HEIGHT_HALF.
- */
- UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
-
- if (ac->datatype == ANIMCONT_NLA) {
- SpaceNla *snla = (SpaceNla *)ac->sl;
- UI_view2d_listview_view_to_cell(v2d, NLACHANNEL_NAMEWIDTH, NLACHANNEL_STEP(snla), 0, (float)NLACHANNEL_HEIGHT_HALF(snla), x, y, NULL, &channel_index);
- }
- else {
- UI_view2d_listview_view_to_cell(v2d, ACHANNEL_NAMEWIDTH, ACHANNEL_STEP(ac), 0, (float)ACHANNEL_HEIGHT_HALF(ac), x, y, NULL, &channel_index);
- }
-
- return channel_index;
+ ARegion *ar;
+ View2D *v2d;
+ int channel_index;
+ float x, y;
+
+ /* get useful pointers from animation context data */
+ ar = ac->ar;
+ v2d = &ar->v2d;
+
+ /* figure out which channel user clicked in
+ * Note: although channels technically start at (y = ACHANNEL_FIRST), we need to adjust by half a channel's height
+ * so that the tops of channels get caught ok. Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use
+ * ACHANNEL_HEIGHT_HALF.
+ */
+ UI_view2d_region_to_view(v2d, mval[0], mval[1], &x, &y);
+
+ if (ac->datatype == ANIMCONT_NLA) {
+ SpaceNla *snla = (SpaceNla *)ac->sl;
+ UI_view2d_listview_view_to_cell(v2d,
+ NLACHANNEL_NAMEWIDTH,
+ NLACHANNEL_STEP(snla),
+ 0,
+ (float)NLACHANNEL_HEIGHT_HALF(snla),
+ x,
+ y,
+ NULL,
+ &channel_index);
+ }
+ else {
+ UI_view2d_listview_view_to_cell(v2d,
+ ACHANNEL_NAMEWIDTH,
+ ACHANNEL_STEP(ac),
+ 0,
+ (float)ACHANNEL_HEIGHT_HALF(ac),
+ x,
+ y,
+ NULL,
+ &channel_index);
+ }
+
+ return channel_index;
}
static int animchannels_rename_invoke(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
{
- bAnimContext ac;
- int channel_index;
+ bAnimContext ac;
+ int channel_index;
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
- channel_index = animchannels_channel_get(&ac, event->mval);
+ channel_index = animchannels_channel_get(&ac, event->mval);
- /* handle click */
- if (rename_anim_channels(&ac, channel_index))
- return OPERATOR_FINISHED;
- else
- /* allow event to be handled by selectall operator */
- return OPERATOR_PASS_THROUGH;
+ /* handle click */
+ if (rename_anim_channels(&ac, channel_index))
+ return OPERATOR_FINISHED;
+ else
+ /* allow event to be handled by selectall operator */
+ return OPERATOR_PASS_THROUGH;
}
static void ANIM_OT_channels_rename(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Rename Channels";
- ot->idname = "ANIM_OT_channels_rename";
- ot->description = "Rename animation channel under mouse";
+ /* identifiers */
+ ot->name = "Rename Channels";
+ ot->idname = "ANIM_OT_channels_rename";
+ ot->description = "Rename animation channel under mouse";
- /* api callbacks */
- ot->invoke = animchannels_rename_invoke;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->invoke = animchannels_rename_invoke;
+ ot->poll = animedit_poll_channels_active;
}
/* ******************** Mouse-Click Operator *********************** */
@@ -2660,357 +2695,355 @@ static void ANIM_OT_channels_rename(wmOperatorType *ot)
static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index, short selectmode)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- int notifierFlags = 0;
-
- /* get the channel that was clicked on */
- /* filter channels */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* get channel from index */
- ale = BLI_findlink(&anim_data, channel_index);
- if (ale == NULL) {
- /* channel not found */
- if (G.debug & G_DEBUG)
- printf("Error: animation channel (index = %d) not found in mouse_anim_channels()\n", channel_index);
-
- ANIM_animdata_freelist(&anim_data);
- return 0;
- }
-
- /* selectmode -1 is a special case for ActionGroups only, which selects all of the channels underneath it only... */
- /* TODO: should this feature be extended to work with other channel types too? */
- if ((selectmode == -1) && (ale->type != ANIMTYPE_GROUP)) {
- /* normal channels should not behave normally in this case */
- ANIM_animdata_freelist(&anim_data);
- return 0;
- }
-
- /* action to take depends on what channel we've got */
- /* WARNING: must keep this in sync with the equivalent function in nla_channels.c */
- switch (ale->type) {
- case ANIMTYPE_SCENE:
- {
- Scene *sce = (Scene *)ale->data;
- AnimData *adt = sce->adt;
-
- /* set selection status */
- if (selectmode == SELECT_INVERT) {
- /* swap select */
- sce->flag ^= SCE_DS_SELECTED;
- if (adt) adt->flag ^= ADT_UI_SELECTED;
- }
- else {
- sce->flag |= SCE_DS_SELECTED;
- if (adt) adt->flag |= ADT_UI_SELECTED;
- }
-
- notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
- break;
- }
- case ANIMTYPE_OBJECT:
- {
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ int notifierFlags = 0;
+
+ /* get the channel that was clicked on */
+ /* filter channels */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* get channel from index */
+ ale = BLI_findlink(&anim_data, channel_index);
+ if (ale == NULL) {
+ /* channel not found */
+ if (G.debug & G_DEBUG)
+ printf("Error: animation channel (index = %d) not found in mouse_anim_channels()\n",
+ channel_index);
+
+ ANIM_animdata_freelist(&anim_data);
+ return 0;
+ }
+
+ /* selectmode -1 is a special case for ActionGroups only, which selects all of the channels underneath it only... */
+ /* TODO: should this feature be extended to work with other channel types too? */
+ if ((selectmode == -1) && (ale->type != ANIMTYPE_GROUP)) {
+ /* normal channels should not behave normally in this case */
+ ANIM_animdata_freelist(&anim_data);
+ return 0;
+ }
+
+ /* action to take depends on what channel we've got */
+ /* WARNING: must keep this in sync with the equivalent function in nla_channels.c */
+ switch (ale->type) {
+ case ANIMTYPE_SCENE: {
+ Scene *sce = (Scene *)ale->data;
+ AnimData *adt = sce->adt;
+
+ /* set selection status */
+ if (selectmode == SELECT_INVERT) {
+ /* swap select */
+ sce->flag ^= SCE_DS_SELECTED;
+ if (adt)
+ adt->flag ^= ADT_UI_SELECTED;
+ }
+ else {
+ sce->flag |= SCE_DS_SELECTED;
+ if (adt)
+ adt->flag |= ADT_UI_SELECTED;
+ }
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ break;
+ }
+ case ANIMTYPE_OBJECT: {
#if 0
- bDopeSheet *ads = (bDopeSheet *)ac->data;
- Scene *sce = (Scene *)ads->source;
+ bDopeSheet *ads = (bDopeSheet *)ac->data;
+ Scene *sce = (Scene *)ads->source;
#endif
- ViewLayer *view_layer = ac->view_layer;
- Base *base = (Base *)ale->data;
- Object *ob = base->object;
- AnimData *adt = ob->adt;
-
- /* set selection status */
- if (base->flag & BASE_SELECTABLE) {
- if (selectmode == SELECT_INVERT) {
- /* swap select */
- ED_object_base_select(base, BA_INVERT);
- BKE_scene_object_base_flag_sync_from_base(base);
-
- if (adt) adt->flag ^= ADT_UI_SELECTED;
- }
- else {
- Base *b;
-
- /* deselect all */
- /* TODO: should this deselect all other types of channels too? */
- for (b = view_layer->object_bases.first; b; b = b->next) {
- ED_object_base_select(b, BA_DESELECT);
- BKE_scene_object_base_flag_sync_from_base(b);
- if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
- }
-
- /* select object now */
- ED_object_base_select(base, BA_SELECT);
- BKE_scene_object_base_flag_sync_from_base(base);
- if (adt) adt->flag |= ADT_UI_SELECTED;
- }
-
- /* change active object - regardless of whether it is now selected [T37883] */
- ED_object_base_activate(C, base); /* adds notifier */
-
- if ((adt) && (adt->flag & ADT_UI_SELECTED))
- adt->flag |= ADT_UI_ACTIVE;
-
- /* ensure we exit editmode on whatever object was active before to avoid getting stuck there - T48747 */
- if (ob != CTX_data_edit_object(C)) {
- ED_object_editmode_exit(C, EM_FREEDATA);
- }
-
- notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
- }
- break;
- }
- case ANIMTYPE_FILLACTD: /* Action Expander */
- case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
- case ANIMTYPE_DSLAM:
- case ANIMTYPE_DSCAM:
- case ANIMTYPE_DSCACHEFILE:
- case ANIMTYPE_DSCUR:
- case ANIMTYPE_DSSKEY:
- case ANIMTYPE_DSWOR:
- case ANIMTYPE_DSPART:
- case ANIMTYPE_DSMBALL:
- case ANIMTYPE_DSARM:
- case ANIMTYPE_DSMESH:
- case ANIMTYPE_DSNTREE:
- case ANIMTYPE_DSTEX:
- case ANIMTYPE_DSLAT:
- case ANIMTYPE_DSLINESTYLE:
- case ANIMTYPE_DSSPK:
- case ANIMTYPE_DSGPENCIL:
- case ANIMTYPE_DSMCLIP:
- {
- /* sanity checking... */
- if (ale->adt) {
- /* select/deselect */
- if (selectmode == SELECT_INVERT) {
- /* inverse selection status of this AnimData block only */
- ale->adt->flag ^= ADT_UI_SELECTED;
- }
- else {
- /* select AnimData block by itself */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- ale->adt->flag |= ADT_UI_SELECTED;
- }
-
- /* set active? */
- if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
- ale->adt->flag |= ADT_UI_ACTIVE;
- }
-
- notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
- break;
- }
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = (bActionGroup *)ale->data;
-
- Object *ob = NULL;
- bPoseChannel *pchan = NULL;
-
-
- /* Armatures-Specific Feature:
- * Since groups are used to collect F-Curves of the same Bone by default
- * (via Keying Sets) so that they can be managed better, we try to make
- * things here easier for animators by mapping group selection to bone
- * selection.
- *
- * Only do this if "Only Selected" dopesheet filter is not active, or else it
- * becomes too unpredictable/tricky to manage
- */
- if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) {
- if ((ale->id) && (GS(ale->id->name) == ID_OB)) {
- ob = (Object *)ale->id;
-
- if (ob->type == OB_ARMATURE) {
- /* Assume for now that any group with corresponding name is what we want
- * (i.e. for an armature whose location is animated, things would break
- * if the user were to add a bone named "Location").
- *
- * TODO: check the first F-Curve or so to be sure...
- */
- pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
- }
- }
- }
-
- /* select/deselect group */
- if (selectmode == SELECT_INVERT) {
- /* inverse selection status of this group only */
- agrp->flag ^= AGRP_SELECTED;
- }
- else if (selectmode == -1) {
- /* select all in group (and deselect everything else) */
- FCurve *fcu;
-
- /* deselect all other channels */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- if (pchan) ED_pose_deselect_all(ob, SEL_DESELECT, false);
-
- /* only select channels in group and group itself */
- for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next)
- fcu->flag |= FCURVE_SELECTED;
- agrp->flag |= AGRP_SELECTED;
- }
- else {
- /* select group by itself */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- if (pchan) ED_pose_deselect_all(ob, SEL_DESELECT, false);
-
- agrp->flag |= AGRP_SELECTED;
- }
-
- /* if group is selected now, make group the 'active' one in the visible list */
- if (agrp->flag & AGRP_SELECTED) {
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
- if (pchan) ED_pose_bone_select(ob, pchan, true);
- }
- else {
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, NULL, ANIMTYPE_GROUP);
- if (pchan) ED_pose_bone_select(ob, pchan, false);
- }
-
- notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
- break;
- }
- case ANIMTYPE_FCURVE:
- case ANIMTYPE_NLACURVE:
- {
- FCurve *fcu = (FCurve *)ale->data;
-
- /* select/deselect */
- if (selectmode == SELECT_INVERT) {
- /* inverse selection status of this F-Curve only */
- fcu->flag ^= FCURVE_SELECTED;
- }
- else {
- /* select F-Curve by itself */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- fcu->flag |= FCURVE_SELECTED;
- }
-
- /* if F-Curve is selected now, make F-Curve the 'active' one in the visible list */
- if (fcu->flag & FCURVE_SELECTED)
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ale->type);
-
- notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
- break;
- }
- case ANIMTYPE_SHAPEKEY:
- {
- KeyBlock *kb = (KeyBlock *)ale->data;
-
- /* select/deselect */
- if (selectmode == SELECT_INVERT) {
- /* inverse selection status of this ShapeKey only */
- kb->flag ^= KEYBLOCK_SEL;
- }
- else {
- /* select ShapeKey by itself */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- kb->flag |= KEYBLOCK_SEL;
- }
-
- notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
- break;
- }
- case ANIMTYPE_NLACONTROLS:
- {
- AnimData *adt = (AnimData *)ale->data;
-
- /* toggle expand
- * - Although the triangle widget already allows this, since there's nothing else that can be done here now,
- * let's just use it for easier expand/collapse for now
- */
- adt->flag ^= ADT_NLA_SKEYS_COLLAPSED;
-
- notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
- break;
- }
- case ANIMTYPE_GPDATABLOCK:
- {
- bGPdata *gpd = (bGPdata *)ale->data;
-
- /* toggle expand
- * - although the triangle widget already allows this, the whole channel can also be used for this purpose
- */
- gpd->flag ^= GP_DATA_EXPAND;
-
- notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
- break;
- }
- case ANIMTYPE_GPLAYER:
- {
- bGPdata *gpd = (bGPdata *)ale->id;
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
- /* select/deselect */
- if (selectmode == SELECT_INVERT) {
- /* invert selection status of this layer only */
- gpl->flag ^= GP_LAYER_SELECT;
- }
- else {
- /* select layer by itself */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- gpl->flag |= GP_LAYER_SELECT;
- }
-
- /* change active layer, if this is selected (since we must always have an active layer) */
- if (gpl->flag & GP_LAYER_SELECT) {
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, gpl, ANIMTYPE_GPLAYER);
- /* update other layer status */
- BKE_gpencil_layer_setactive(gpd, gpl);
- }
-
- /* Grease Pencil updates */
- WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
- notifierFlags |= (ND_ANIMCHAN | NA_EDITED); /* Animation Editors updates */
- break;
- }
- case ANIMTYPE_MASKDATABLOCK:
- {
- Mask *mask = (Mask *)ale->data;
-
- /* toggle expand
- * - although the triangle widget already allows this, the whole channel can also be used for this purpose
- */
- mask->flag ^= MASK_ANIMF_EXPAND;
-
- notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
- break;
- }
- case ANIMTYPE_MASKLAYER:
- {
- MaskLayer *masklay = (MaskLayer *)ale->data;
-
- /* select/deselect */
- if (selectmode == SELECT_INVERT) {
- /* invert selection status of this layer only */
- masklay->flag ^= MASK_LAYERFLAG_SELECT;
- }
- else {
- /* select layer by itself */
- ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
- masklay->flag |= MASK_LAYERFLAG_SELECT;
- }
-
- notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
- break;
- }
- default:
- if (G.debug & G_DEBUG)
- printf("Error: Invalid channel type in mouse_anim_channels()\n");
- break;
- }
-
- /* free channels */
- ANIM_animdata_freelist(&anim_data);
-
- /* return notifier flags */
- return notifierFlags;
+ ViewLayer *view_layer = ac->view_layer;
+ Base *base = (Base *)ale->data;
+ Object *ob = base->object;
+ AnimData *adt = ob->adt;
+
+ /* set selection status */
+ if (base->flag & BASE_SELECTABLE) {
+ if (selectmode == SELECT_INVERT) {
+ /* swap select */
+ ED_object_base_select(base, BA_INVERT);
+ BKE_scene_object_base_flag_sync_from_base(base);
+
+ if (adt)
+ adt->flag ^= ADT_UI_SELECTED;
+ }
+ else {
+ Base *b;
+
+ /* deselect all */
+ /* TODO: should this deselect all other types of channels too? */
+ for (b = view_layer->object_bases.first; b; b = b->next) {
+ ED_object_base_select(b, BA_DESELECT);
+ BKE_scene_object_base_flag_sync_from_base(b);
+ if (b->object->adt)
+ b->object->adt->flag &= ~(ADT_UI_SELECTED | ADT_UI_ACTIVE);
+ }
+
+ /* select object now */
+ ED_object_base_select(base, BA_SELECT);
+ BKE_scene_object_base_flag_sync_from_base(base);
+ if (adt)
+ adt->flag |= ADT_UI_SELECTED;
+ }
+
+ /* change active object - regardless of whether it is now selected [T37883] */
+ ED_object_base_activate(C, base); /* adds notifier */
+
+ if ((adt) && (adt->flag & ADT_UI_SELECTED))
+ adt->flag |= ADT_UI_ACTIVE;
+
+ /* ensure we exit editmode on whatever object was active before to avoid getting stuck there - T48747 */
+ if (ob != CTX_data_edit_object(C)) {
+ ED_object_editmode_exit(C, EM_FREEDATA);
+ }
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ }
+ break;
+ }
+ case ANIMTYPE_FILLACTD: /* Action Expander */
+ case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
+ case ANIMTYPE_DSLAM:
+ case ANIMTYPE_DSCAM:
+ case ANIMTYPE_DSCACHEFILE:
+ case ANIMTYPE_DSCUR:
+ case ANIMTYPE_DSSKEY:
+ case ANIMTYPE_DSWOR:
+ case ANIMTYPE_DSPART:
+ case ANIMTYPE_DSMBALL:
+ case ANIMTYPE_DSARM:
+ case ANIMTYPE_DSMESH:
+ case ANIMTYPE_DSNTREE:
+ case ANIMTYPE_DSTEX:
+ case ANIMTYPE_DSLAT:
+ case ANIMTYPE_DSLINESTYLE:
+ case ANIMTYPE_DSSPK:
+ case ANIMTYPE_DSGPENCIL:
+ case ANIMTYPE_DSMCLIP: {
+ /* sanity checking... */
+ if (ale->adt) {
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* inverse selection status of this AnimData block only */
+ ale->adt->flag ^= ADT_UI_SELECTED;
+ }
+ else {
+ /* select AnimData block by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ ale->adt->flag |= ADT_UI_SELECTED;
+ }
+
+ /* set active? */
+ if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
+ ale->adt->flag |= ADT_UI_ACTIVE;
+ }
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ break;
+ }
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+
+ Object *ob = NULL;
+ bPoseChannel *pchan = NULL;
+
+ /* Armatures-Specific Feature:
+ * Since groups are used to collect F-Curves of the same Bone by default
+ * (via Keying Sets) so that they can be managed better, we try to make
+ * things here easier for animators by mapping group selection to bone
+ * selection.
+ *
+ * Only do this if "Only Selected" dopesheet filter is not active, or else it
+ * becomes too unpredictable/tricky to manage
+ */
+ if ((ac->ads->filterflag & ADS_FILTER_ONLYSEL) == 0) {
+ if ((ale->id) && (GS(ale->id->name) == ID_OB)) {
+ ob = (Object *)ale->id;
+
+ if (ob->type == OB_ARMATURE) {
+ /* Assume for now that any group with corresponding name is what we want
+ * (i.e. for an armature whose location is animated, things would break
+ * if the user were to add a bone named "Location").
+ *
+ * TODO: check the first F-Curve or so to be sure...
+ */
+ pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
+ }
+ }
+ }
+
+ /* select/deselect group */
+ if (selectmode == SELECT_INVERT) {
+ /* inverse selection status of this group only */
+ agrp->flag ^= AGRP_SELECTED;
+ }
+ else if (selectmode == -1) {
+ /* select all in group (and deselect everything else) */
+ FCurve *fcu;
+
+ /* deselect all other channels */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ if (pchan)
+ ED_pose_deselect_all(ob, SEL_DESELECT, false);
+
+ /* only select channels in group and group itself */
+ for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next)
+ fcu->flag |= FCURVE_SELECTED;
+ agrp->flag |= AGRP_SELECTED;
+ }
+ else {
+ /* select group by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ if (pchan)
+ ED_pose_deselect_all(ob, SEL_DESELECT, false);
+
+ agrp->flag |= AGRP_SELECTED;
+ }
+
+ /* if group is selected now, make group the 'active' one in the visible list */
+ if (agrp->flag & AGRP_SELECTED) {
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, agrp, ANIMTYPE_GROUP);
+ if (pchan)
+ ED_pose_bone_select(ob, pchan, true);
+ }
+ else {
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, NULL, ANIMTYPE_GROUP);
+ if (pchan)
+ ED_pose_bone_select(ob, pchan, false);
+ }
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ break;
+ }
+ case ANIMTYPE_FCURVE:
+ case ANIMTYPE_NLACURVE: {
+ FCurve *fcu = (FCurve *)ale->data;
+
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* inverse selection status of this F-Curve only */
+ fcu->flag ^= FCURVE_SELECTED;
+ }
+ else {
+ /* select F-Curve by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ fcu->flag |= FCURVE_SELECTED;
+ }
+
+ /* if F-Curve is selected now, make F-Curve the 'active' one in the visible list */
+ if (fcu->flag & FCURVE_SELECTED)
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ale->type);
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ break;
+ }
+ case ANIMTYPE_SHAPEKEY: {
+ KeyBlock *kb = (KeyBlock *)ale->data;
+
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* inverse selection status of this ShapeKey only */
+ kb->flag ^= KEYBLOCK_SEL;
+ }
+ else {
+ /* select ShapeKey by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ kb->flag |= KEYBLOCK_SEL;
+ }
+
+ notifierFlags |= (ND_ANIMCHAN | NA_SELECTED);
+ break;
+ }
+ case ANIMTYPE_NLACONTROLS: {
+ AnimData *adt = (AnimData *)ale->data;
+
+ /* toggle expand
+ * - Although the triangle widget already allows this, since there's nothing else that can be done here now,
+ * let's just use it for easier expand/collapse for now
+ */
+ adt->flag ^= ADT_NLA_SKEYS_COLLAPSED;
+
+ notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
+ break;
+ }
+ case ANIMTYPE_GPDATABLOCK: {
+ bGPdata *gpd = (bGPdata *)ale->data;
+
+ /* toggle expand
+ * - although the triangle widget already allows this, the whole channel can also be used for this purpose
+ */
+ gpd->flag ^= GP_DATA_EXPAND;
+
+ notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
+ break;
+ }
+ case ANIMTYPE_GPLAYER: {
+ bGPdata *gpd = (bGPdata *)ale->id;
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* invert selection status of this layer only */
+ gpl->flag ^= GP_LAYER_SELECT;
+ }
+ else {
+ /* select layer by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ gpl->flag |= GP_LAYER_SELECT;
+ }
+
+ /* change active layer, if this is selected (since we must always have an active layer) */
+ if (gpl->flag & GP_LAYER_SELECT) {
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, gpl, ANIMTYPE_GPLAYER);
+ /* update other layer status */
+ BKE_gpencil_layer_setactive(gpd, gpl);
+ }
+
+ /* Grease Pencil updates */
+ WM_event_add_notifier(C, NC_GPENCIL | ND_DATA | NA_EDITED | ND_SPACE_PROPERTIES, NULL);
+ notifierFlags |= (ND_ANIMCHAN | NA_EDITED); /* Animation Editors updates */
+ break;
+ }
+ case ANIMTYPE_MASKDATABLOCK: {
+ Mask *mask = (Mask *)ale->data;
+
+ /* toggle expand
+ * - although the triangle widget already allows this, the whole channel can also be used for this purpose
+ */
+ mask->flag ^= MASK_ANIMF_EXPAND;
+
+ notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
+ break;
+ }
+ case ANIMTYPE_MASKLAYER: {
+ MaskLayer *masklay = (MaskLayer *)ale->data;
+
+ /* select/deselect */
+ if (selectmode == SELECT_INVERT) {
+ /* invert selection status of this layer only */
+ masklay->flag ^= MASK_LAYERFLAG_SELECT;
+ }
+ else {
+ /* select layer by itself */
+ ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, false, ACHANNEL_SETFLAG_CLEAR);
+ masklay->flag |= MASK_LAYERFLAG_SELECT;
+ }
+
+ notifierFlags |= (ND_ANIMCHAN | NA_EDITED);
+ break;
+ }
+ default:
+ if (G.debug & G_DEBUG)
+ printf("Error: Invalid channel type in mouse_anim_channels()\n");
+ break;
+ }
+
+ /* free channels */
+ ANIM_animdata_freelist(&anim_data);
+
+ /* return notifier flags */
+ return notifierFlags;
}
/* ------------------- */
@@ -3018,177 +3051,188 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index,
/* handle clicking */
static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- bAnimContext ac;
- ARegion *ar;
- View2D *v2d;
- int channel_index;
- int notifierFlags = 0;
- short selectmode;
- float x, y;
-
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- /* get useful pointers from animation context data */
- ar = ac.ar;
- v2d = &ar->v2d;
-
- /* select mode is either replace (deselect all, then add) or add/extend */
- if (RNA_boolean_get(op->ptr, "extend")) {
- selectmode = SELECT_INVERT;
- }
- else if (RNA_boolean_get(op->ptr, "children_only")) {
- /* this is a bit of a special case for ActionGroups only...
- * should it be removed or extended to all instead? */
- selectmode = -1;
- }
- else {
- selectmode = SELECT_REPLACE;
- }
-
- /* figure out which channel user clicked in
- *
- * Note:
- * although channels technically start at (y = ACHANNEL_FIRST),
- * we need to adjust by half a channel's height so that the tops of channels get caught ok.
- * Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use ACHANNEL_HEIGHT_HALF.
- */
- UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
- UI_view2d_listview_view_to_cell(v2d, ACHANNEL_NAMEWIDTH, ACHANNEL_STEP(&ac), 0, (float)ACHANNEL_HEIGHT_HALF(&ac), x, y, NULL, &channel_index);
-
- /* handle mouse-click in the relevant channel then */
- notifierFlags = mouse_anim_channels(C, &ac, channel_index, selectmode);
-
- /* set notifier that things have changed */
- WM_event_add_notifier(C, NC_ANIMATION | notifierFlags, NULL);
-
- return OPERATOR_FINISHED;
+ bAnimContext ac;
+ ARegion *ar;
+ View2D *v2d;
+ int channel_index;
+ int notifierFlags = 0;
+ short selectmode;
+ float x, y;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ /* get useful pointers from animation context data */
+ ar = ac.ar;
+ v2d = &ar->v2d;
+
+ /* select mode is either replace (deselect all, then add) or add/extend */
+ if (RNA_boolean_get(op->ptr, "extend")) {
+ selectmode = SELECT_INVERT;
+ }
+ else if (RNA_boolean_get(op->ptr, "children_only")) {
+ /* this is a bit of a special case for ActionGroups only...
+ * should it be removed or extended to all instead? */
+ selectmode = -1;
+ }
+ else {
+ selectmode = SELECT_REPLACE;
+ }
+
+ /* figure out which channel user clicked in
+ *
+ * Note:
+ * although channels technically start at (y = ACHANNEL_FIRST),
+ * we need to adjust by half a channel's height so that the tops of channels get caught ok.
+ * Since ACHANNEL_FIRST is really ACHANNEL_HEIGHT, we simply use ACHANNEL_HEIGHT_HALF.
+ */
+ UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, &y);
+ UI_view2d_listview_view_to_cell(v2d,
+ ACHANNEL_NAMEWIDTH,
+ ACHANNEL_STEP(&ac),
+ 0,
+ (float)ACHANNEL_HEIGHT_HALF(&ac),
+ x,
+ y,
+ NULL,
+ &channel_index);
+
+ /* handle mouse-click in the relevant channel then */
+ notifierFlags = mouse_anim_channels(C, &ac, channel_index, selectmode);
+
+ /* set notifier that things have changed */
+ WM_event_add_notifier(C, NC_ANIMATION | notifierFlags, NULL);
+
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_channels_click(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Mouse Click on Channels";
- ot->idname = "ANIM_OT_channels_click";
- ot->description = "Handle mouse-clicks over animation channels";
+ /* identifiers */
+ ot->name = "Mouse Click on Channels";
+ ot->idname = "ANIM_OT_channels_click";
+ ot->description = "Handle mouse-clicks over animation channels";
- /* api callbacks */
- ot->invoke = animchannels_mouseclick_invoke;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->invoke = animchannels_mouseclick_invoke;
+ ot->poll = animedit_poll_channels_active;
- /* flags */
- ot->flag = OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_UNDO;
- /* properties */
- /* NOTE: don't save settings, otherwise, can end up with some weird behavior (sticky extend) */
- prop = RNA_def_boolean(ot->srna, "extend", false, "Extend Select", ""); // SHIFTKEY
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ /* properties */
+ /* NOTE: don't save settings, otherwise, can end up with some weird behavior (sticky extend) */
+ prop = RNA_def_boolean(ot->srna, "extend", false, "Extend Select", ""); // SHIFTKEY
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
- prop = RNA_def_boolean(ot->srna, "children_only", false, "Select Children Only", ""); // CTRLKEY|SHIFTKEY
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(
+ ot->srna, "children_only", false, "Select Children Only", ""); // CTRLKEY|SHIFTKEY
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
static bool select_anim_channel_keys(bAnimContext *ac, int channel_index, bool extend)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- bool success = false;
- FCurve *fcu;
- int i;
-
- /* get the channel that was clicked on */
- /* filter channels */
- filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* get channel from index */
- ale = BLI_findlink(&anim_data, channel_index);
- if (ale == NULL) {
- /* channel not found */
- if (G.debug & G_DEBUG)
- printf("Error: animation channel (index = %d) not found in rename_anim_channels()\n", channel_index);
-
- ANIM_animdata_freelist(&anim_data);
- return false;
- }
-
- fcu = (FCurve *)ale->key_data;
- success = (fcu != NULL);
-
- ANIM_animdata_freelist(&anim_data);
-
- /* F-Curve may not have any keyframes */
- if (fcu && fcu->bezt) {
- BezTriple *bezt;
-
- if (!extend) {
- filter = (ANIMFILTER_DATA_VISIBLE);
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- for (ale = anim_data.first; ale; ale = ale->next) {
- FCurve *fcu_inner = (FCurve *)ale->key_data;
-
- if (fcu_inner != NULL && fcu_inner->bezt != NULL) {
- for (i = 0, bezt = fcu_inner->bezt; i < fcu_inner->totvert; i++, bezt++) {
- bezt->f2 = bezt->f1 = bezt->f3 = 0;
- }
- }
- }
-
- ANIM_animdata_freelist(&anim_data);
- }
-
- for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
- bezt->f2 = bezt->f1 = bezt->f3 = SELECT;
- }
- }
-
- /* free temp data and tag for refresh */
- ED_region_tag_redraw(ac->ar);
- return success;
-}
-
-static int animchannels_channel_select_keys_invoke(bContext *C, wmOperator *op, const wmEvent *event)
-{
- bAnimContext ac;
- int channel_index;
- bool extend = RNA_boolean_get(op->ptr, "extend");
-
- /* get editor data */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return OPERATOR_CANCELLED;
-
- channel_index = animchannels_channel_get(&ac, event->mval);
-
- /* handle click */
- if (select_anim_channel_keys(&ac, channel_index, extend)) {
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
- return OPERATOR_FINISHED;
- }
- else
- /* allow event to be handled by selectall operator */
- return OPERATOR_PASS_THROUGH;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ bool success = false;
+ FCurve *fcu;
+ int i;
+
+ /* get the channel that was clicked on */
+ /* filter channels */
+ filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* get channel from index */
+ ale = BLI_findlink(&anim_data, channel_index);
+ if (ale == NULL) {
+ /* channel not found */
+ if (G.debug & G_DEBUG)
+ printf("Error: animation channel (index = %d) not found in rename_anim_channels()\n",
+ channel_index);
+
+ ANIM_animdata_freelist(&anim_data);
+ return false;
+ }
+
+ fcu = (FCurve *)ale->key_data;
+ success = (fcu != NULL);
+
+ ANIM_animdata_freelist(&anim_data);
+
+ /* F-Curve may not have any keyframes */
+ if (fcu && fcu->bezt) {
+ BezTriple *bezt;
+
+ if (!extend) {
+ filter = (ANIMFILTER_DATA_VISIBLE);
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ FCurve *fcu_inner = (FCurve *)ale->key_data;
+
+ if (fcu_inner != NULL && fcu_inner->bezt != NULL) {
+ for (i = 0, bezt = fcu_inner->bezt; i < fcu_inner->totvert; i++, bezt++) {
+ bezt->f2 = bezt->f1 = bezt->f3 = 0;
+ }
+ }
+ }
+
+ ANIM_animdata_freelist(&anim_data);
+ }
+
+ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ bezt->f2 = bezt->f1 = bezt->f3 = SELECT;
+ }
+ }
+
+ /* free temp data and tag for refresh */
+ ED_region_tag_redraw(ac->ar);
+ return success;
+}
+
+static int animchannels_channel_select_keys_invoke(bContext *C,
+ wmOperator *op,
+ const wmEvent *event)
+{
+ bAnimContext ac;
+ int channel_index;
+ bool extend = RNA_boolean_get(op->ptr, "extend");
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+
+ channel_index = animchannels_channel_get(&ac, event->mval);
+
+ /* handle click */
+ if (select_anim_channel_keys(&ac, channel_index, extend)) {
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
+ return OPERATOR_FINISHED;
+ }
+ else
+ /* allow event to be handled by selectall operator */
+ return OPERATOR_PASS_THROUGH;
}
static void ANIM_OT_channel_select_keys(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Select Channel keyframes";
- ot->idname = "ANIM_OT_channel_select_keys";
- ot->description = "Select all keyframes of channel under mouse";
+ /* identifiers */
+ ot->name = "Select Channel keyframes";
+ ot->idname = "ANIM_OT_channel_select_keys";
+ ot->description = "Select all keyframes of channel under mouse";
- /* api callbacks */
- ot->invoke = animchannels_channel_select_keys_invoke;
- ot->poll = animedit_poll_channels_active;
+ /* api callbacks */
+ ot->invoke = animchannels_channel_select_keys_invoke;
+ ot->poll = animedit_poll_channels_active;
- prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "extend", false, "Extend", "Extend selection");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
/* ************************************************************************** */
@@ -3196,41 +3240,41 @@ static void ANIM_OT_channel_select_keys(wmOperatorType *ot)
void ED_operatortypes_animchannels(void)
{
- WM_operatortype_append(ANIM_OT_channels_select_all);
- WM_operatortype_append(ANIM_OT_channels_select_box);
+ WM_operatortype_append(ANIM_OT_channels_select_all);
+ WM_operatortype_append(ANIM_OT_channels_select_box);
- WM_operatortype_append(ANIM_OT_channels_click);
- WM_operatortype_append(ANIM_OT_channel_select_keys);
- WM_operatortype_append(ANIM_OT_channels_rename);
+ WM_operatortype_append(ANIM_OT_channels_click);
+ WM_operatortype_append(ANIM_OT_channel_select_keys);
+ WM_operatortype_append(ANIM_OT_channels_rename);
- WM_operatortype_append(ANIM_OT_channels_find);
+ WM_operatortype_append(ANIM_OT_channels_find);
- WM_operatortype_append(ANIM_OT_channels_setting_enable);
- WM_operatortype_append(ANIM_OT_channels_setting_disable);
- WM_operatortype_append(ANIM_OT_channels_setting_toggle);
+ WM_operatortype_append(ANIM_OT_channels_setting_enable);
+ WM_operatortype_append(ANIM_OT_channels_setting_disable);
+ WM_operatortype_append(ANIM_OT_channels_setting_toggle);
- WM_operatortype_append(ANIM_OT_channels_delete);
+ WM_operatortype_append(ANIM_OT_channels_delete);
- /* XXX does this need to be a separate operator? */
- WM_operatortype_append(ANIM_OT_channels_editable_toggle);
+ /* XXX does this need to be a separate operator? */
+ WM_operatortype_append(ANIM_OT_channels_editable_toggle);
- WM_operatortype_append(ANIM_OT_channels_move);
+ WM_operatortype_append(ANIM_OT_channels_move);
- WM_operatortype_append(ANIM_OT_channels_expand);
- WM_operatortype_append(ANIM_OT_channels_collapse);
+ WM_operatortype_append(ANIM_OT_channels_expand);
+ WM_operatortype_append(ANIM_OT_channels_collapse);
- WM_operatortype_append(ANIM_OT_channels_fcurves_enable);
+ WM_operatortype_append(ANIM_OT_channels_fcurves_enable);
- WM_operatortype_append(ANIM_OT_channels_clean_empty);
+ WM_operatortype_append(ANIM_OT_channels_clean_empty);
- WM_operatortype_append(ANIM_OT_channels_group);
- WM_operatortype_append(ANIM_OT_channels_ungroup);
+ WM_operatortype_append(ANIM_OT_channels_group);
+ WM_operatortype_append(ANIM_OT_channels_ungroup);
}
// TODO: check on a poll callback for this, to get hotkeys into menus
void ED_keymap_animchannels(wmKeyConfig *keyconf)
{
- WM_keymap_ensure(keyconf, "Animation Channels", 0, 0);
+ WM_keymap_ensure(keyconf, "Animation Channels", 0, 0);
}
/* ************************************************************************** */
diff --git a/source/blender/editors/animation/anim_deps.c b/source/blender/editors/animation/anim_deps.c
index dfb1a456364..53fec2e1ef7 100644
--- a/source/blender/editors/animation/anim_deps.c
+++ b/source/blender/editors/animation/anim_deps.c
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
#include <string.h>
#include "MEM_guardedalloc.h"
@@ -59,58 +58,68 @@
*/
void ANIM_list_elem_update(Main *bmain, Scene *scene, bAnimListElem *ale)
{
- ID *id;
- FCurve *fcu;
- AnimData *adt;
-
- id = ale->id;
- if (!id)
- return;
-
- /* tag AnimData for refresh so that other views will update in realtime with these changes */
- adt = BKE_animdata_from_id(id);
- if (adt) {
- DEG_id_tag_update(id, ID_RECALC_ANIMATION);
- if (adt->action != NULL) {
- DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION);
- }
- }
-
- /* Tag copy on the main object if updating anything directly inside AnimData */
- if (ELEM(ale->type, ANIMTYPE_ANIMDATA, ANIMTYPE_NLAACTION, ANIMTYPE_NLATRACK, ANIMTYPE_NLACURVE)) {
- DEG_id_tag_update(id, ID_RECALC_ANIMATION);
- return;
- }
-
- /* update data */
- fcu = (ale->datatype == ALE_FCURVE) ? ale->key_data : NULL;
-
- if (fcu && fcu->rna_path) {
- /* if we have an fcurve, call the update for the property we
- * are editing, this is then expected to do the proper redraws
- * and depsgraph updates */
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
-
- RNA_id_pointer_create(id, &id_ptr);
-
- if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop))
- RNA_property_update_main(bmain, scene, &ptr, prop);
- }
- else {
- /* in other case we do standard depsgraph update, ideally
- * we'd be calling property update functions here too ... */
- DEG_id_tag_update(id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION); // XXX or do we want something more restrictive?
- }
+ ID *id;
+ FCurve *fcu;
+ AnimData *adt;
+
+ id = ale->id;
+ if (!id)
+ return;
+
+ /* tag AnimData for refresh so that other views will update in realtime with these changes */
+ adt = BKE_animdata_from_id(id);
+ if (adt) {
+ DEG_id_tag_update(id, ID_RECALC_ANIMATION);
+ if (adt->action != NULL) {
+ DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION);
+ }
+ }
+
+ /* Tag copy on the main object if updating anything directly inside AnimData */
+ if (ELEM(ale->type,
+ ANIMTYPE_ANIMDATA,
+ ANIMTYPE_NLAACTION,
+ ANIMTYPE_NLATRACK,
+ ANIMTYPE_NLACURVE)) {
+ DEG_id_tag_update(id, ID_RECALC_ANIMATION);
+ return;
+ }
+
+ /* update data */
+ fcu = (ale->datatype == ALE_FCURVE) ? ale->key_data : NULL;
+
+ if (fcu && fcu->rna_path) {
+ /* if we have an fcurve, call the update for the property we
+ * are editing, this is then expected to do the proper redraws
+ * and depsgraph updates */
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+
+ RNA_id_pointer_create(id, &id_ptr);
+
+ if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop))
+ RNA_property_update_main(bmain, scene, &ptr, prop);
+ }
+ else {
+ /* in other case we do standard depsgraph update, ideally
+ * we'd be calling property update functions here too ... */
+ DEG_id_tag_update(id,
+ ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY |
+ ID_RECALC_ANIMATION); // XXX or do we want something more restrictive?
+ }
}
/* tags the given ID block for refreshes (if applicable) due to
* Animation Editor editing */
void ANIM_id_update(Main *bmain, ID *id)
{
- if (id) {
- DEG_id_tag_update_ex(bmain, id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY | ID_RECALC_ANIMATION); // XXX or do we want something more restrictive?
- }
+ if (id) {
+ DEG_id_tag_update_ex(
+ bmain,
+ id,
+ ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY |
+ ID_RECALC_ANIMATION); // XXX or do we want something more restrictive?
+ }
}
/* **************************** animation data <-> data syncing ******************************** */
@@ -126,161 +135,165 @@ void ANIM_id_update(Main *bmain, ID *id)
/* perform syncing updates for Action Groups */
static void animchan_sync_group(bAnimContext *ac, bAnimListElem *ale, bActionGroup **active_agrp)
{
- bActionGroup *agrp = (bActionGroup *)ale->data;
- ID *owner_id = ale->id;
-
- /* major priority is selection status
- * so we need both a group and an owner
- */
- if (ELEM(NULL, agrp, owner_id))
- return;
-
- /* for standard Objects, check if group is the name of some bone */
- if (GS(owner_id->name) == ID_OB) {
- Object *ob = (Object *)owner_id;
-
- /* check if there are bones, and whether the name matches any
- * NOTE: this feature will only really work if groups by default contain the F-Curves for a single bone
- */
- if (ob->pose) {
- bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
- bArmature *arm = ob->data;
-
- if (pchan) {
- bActionGroup *bgrp;
-
- /* if one matches, sync the selection status */
- if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))
- agrp->flag |= AGRP_SELECTED;
- else
- agrp->flag &= ~AGRP_SELECTED;
-
- /* also sync active group status */
- if ((ob == ac->obact) && (pchan->bone == arm->act_bone)) {
- /* if no previous F-Curve has active flag, then we're the first and only one to get it */
- if (*active_agrp == NULL) {
- agrp->flag |= AGRP_ACTIVE;
- *active_agrp = agrp;
- }
- else {
- /* someone else has already taken it - set as not active */
- agrp->flag &= ~AGRP_ACTIVE;
- }
- }
- else {
- /* this can't possibly be active now */
- agrp->flag &= ~AGRP_ACTIVE;
- }
-
- /* sync group colors */
- bgrp = (bActionGroup *)BLI_findlink(&ob->pose->agroups, (pchan->agrp_index - 1));
- if (bgrp) {
- agrp->customCol = bgrp->customCol;
- action_group_colors_sync(agrp, bgrp);
- }
- }
- }
- }
+ bActionGroup *agrp = (bActionGroup *)ale->data;
+ ID *owner_id = ale->id;
+
+ /* major priority is selection status
+ * so we need both a group and an owner
+ */
+ if (ELEM(NULL, agrp, owner_id))
+ return;
+
+ /* for standard Objects, check if group is the name of some bone */
+ if (GS(owner_id->name) == ID_OB) {
+ Object *ob = (Object *)owner_id;
+
+ /* check if there are bones, and whether the name matches any
+ * NOTE: this feature will only really work if groups by default contain the F-Curves for a single bone
+ */
+ if (ob->pose) {
+ bPoseChannel *pchan = BKE_pose_channel_find_name(ob->pose, agrp->name);
+ bArmature *arm = ob->data;
+
+ if (pchan) {
+ bActionGroup *bgrp;
+
+ /* if one matches, sync the selection status */
+ if ((pchan->bone) && (pchan->bone->flag & BONE_SELECTED))
+ agrp->flag |= AGRP_SELECTED;
+ else
+ agrp->flag &= ~AGRP_SELECTED;
+
+ /* also sync active group status */
+ if ((ob == ac->obact) && (pchan->bone == arm->act_bone)) {
+ /* if no previous F-Curve has active flag, then we're the first and only one to get it */
+ if (*active_agrp == NULL) {
+ agrp->flag |= AGRP_ACTIVE;
+ *active_agrp = agrp;
+ }
+ else {
+ /* someone else has already taken it - set as not active */
+ agrp->flag &= ~AGRP_ACTIVE;
+ }
+ }
+ else {
+ /* this can't possibly be active now */
+ agrp->flag &= ~AGRP_ACTIVE;
+ }
+
+ /* sync group colors */
+ bgrp = (bActionGroup *)BLI_findlink(&ob->pose->agroups, (pchan->agrp_index - 1));
+ if (bgrp) {
+ agrp->customCol = bgrp->customCol;
+ action_group_colors_sync(agrp, bgrp);
+ }
+ }
+ }
+ }
}
/* perform syncing updates for F-Curves */
-static void animchan_sync_fcurve(bAnimContext *UNUSED(ac), bAnimListElem *ale, FCurve **active_fcurve)
+static void animchan_sync_fcurve(bAnimContext *UNUSED(ac),
+ bAnimListElem *ale,
+ FCurve **active_fcurve)
{
- FCurve *fcu = (FCurve *)ale->data;
- ID *owner_id = ale->id;
-
- /* major priority is selection status, so refer to the checks done in anim_filter.c
- * skip_fcurve_selected_data() for reference about what's going on here...
- */
- if (ELEM(NULL, fcu, fcu->rna_path, owner_id))
- return;
-
- if (GS(owner_id->name) == ID_SCE) {
- Scene *scene = (Scene *)owner_id;
-
- /* only affect if F-Curve involves sequence_editor.sequences */
- if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
- Editing *ed = BKE_sequencer_editing_get(scene, false);
- Sequence *seq;
- char *seq_name;
-
- /* get strip name, and check if this strip is selected */
- seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
- seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false);
- if (seq_name) MEM_freeN(seq_name);
-
- /* update selection status */
- if (seq) {
- if (seq->flag & SELECT)
- fcu->flag |= FCURVE_SELECTED;
- else
- fcu->flag &= ~FCURVE_SELECTED;
- }
- }
- }
- else if (GS(owner_id->name) == ID_NT) {
- bNodeTree *ntree = (bNodeTree *)owner_id;
-
- /* check for selected nodes */
- if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) {
- bNode *node;
- char *node_name;
-
- /* get strip name, and check if this strip is selected */
- node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes[");
- node = nodeFindNodebyName(ntree, node_name);
- if (node_name) MEM_freeN(node_name);
-
- /* update selection/active status */
- if (node) {
- /* update selection status */
- if (node->flag & NODE_SELECT)
- fcu->flag |= FCURVE_SELECTED;
- else
- fcu->flag &= ~FCURVE_SELECTED;
-
- /* update active status */
- /* XXX: this may interfere with setting bones as active if both exist at once;
- * then again, if that's the case, production setups aren't likely to be animating
- * nodes while working with bones?
- */
- if (node->flag & NODE_ACTIVE) {
- if (*active_fcurve == NULL) {
- fcu->flag |= FCURVE_ACTIVE;
- *active_fcurve = fcu;
- }
- else {
- fcu->flag &= ~FCURVE_ACTIVE;
- }
- }
- else {
- fcu->flag &= ~FCURVE_ACTIVE;
- }
- }
- }
- }
+ FCurve *fcu = (FCurve *)ale->data;
+ ID *owner_id = ale->id;
+
+ /* major priority is selection status, so refer to the checks done in anim_filter.c
+ * skip_fcurve_selected_data() for reference about what's going on here...
+ */
+ if (ELEM(NULL, fcu, fcu->rna_path, owner_id))
+ return;
+
+ if (GS(owner_id->name) == ID_SCE) {
+ Scene *scene = (Scene *)owner_id;
+
+ /* only affect if F-Curve involves sequence_editor.sequences */
+ if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+ Sequence *seq;
+ char *seq_name;
+
+ /* get strip name, and check if this strip is selected */
+ seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
+ seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false);
+ if (seq_name)
+ MEM_freeN(seq_name);
+
+ /* update selection status */
+ if (seq) {
+ if (seq->flag & SELECT)
+ fcu->flag |= FCURVE_SELECTED;
+ else
+ fcu->flag &= ~FCURVE_SELECTED;
+ }
+ }
+ }
+ else if (GS(owner_id->name) == ID_NT) {
+ bNodeTree *ntree = (bNodeTree *)owner_id;
+
+ /* check for selected nodes */
+ if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) {
+ bNode *node;
+ char *node_name;
+
+ /* get strip name, and check if this strip is selected */
+ node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes[");
+ node = nodeFindNodebyName(ntree, node_name);
+ if (node_name)
+ MEM_freeN(node_name);
+
+ /* update selection/active status */
+ if (node) {
+ /* update selection status */
+ if (node->flag & NODE_SELECT)
+ fcu->flag |= FCURVE_SELECTED;
+ else
+ fcu->flag &= ~FCURVE_SELECTED;
+
+ /* update active status */
+ /* XXX: this may interfere with setting bones as active if both exist at once;
+ * then again, if that's the case, production setups aren't likely to be animating
+ * nodes while working with bones?
+ */
+ if (node->flag & NODE_ACTIVE) {
+ if (*active_fcurve == NULL) {
+ fcu->flag |= FCURVE_ACTIVE;
+ *active_fcurve = fcu;
+ }
+ else {
+ fcu->flag &= ~FCURVE_ACTIVE;
+ }
+ }
+ else {
+ fcu->flag &= ~FCURVE_ACTIVE;
+ }
+ }
+ }
+ }
}
/* perform syncing updates for GPencil Layers */
static void animchan_sync_gplayer(bAnimContext *UNUSED(ac), bAnimListElem *ale)
{
- bGPDlayer *gpl = (bGPDlayer *)ale->data;
-
- /* Make sure the selection flags agree with the "active" flag.
- * The selection flags are used in the Dopesheet only, whereas
- * the active flag is used everywhere else. Hence, we try to
- * sync these here so that it all seems to be have as the user
- * expects - T50184
- *
- * Assume that we only really do this when the active status changes.
- * (NOTE: This may prove annoying if it means selection is always lost)
- */
- if (gpl->flag & GP_LAYER_ACTIVE) {
- gpl->flag |= GP_LAYER_SELECT;
- }
- else {
- gpl->flag &= ~GP_LAYER_SELECT;
- }
+ bGPDlayer *gpl = (bGPDlayer *)ale->data;
+
+ /* Make sure the selection flags agree with the "active" flag.
+ * The selection flags are used in the Dopesheet only, whereas
+ * the active flag is used everywhere else. Hence, we try to
+ * sync these here so that it all seems to be have as the user
+ * expects - T50184
+ *
+ * Assume that we only really do this when the active status changes.
+ * (NOTE: This may prove annoying if it means selection is always lost)
+ */
+ if (gpl->flag & GP_LAYER_ACTIVE) {
+ gpl->flag |= GP_LAYER_SELECT;
+ }
+ else {
+ gpl->flag &= ~GP_LAYER_SELECT;
+ }
}
/* ---------------- */
@@ -288,131 +301,135 @@ static void animchan_sync_gplayer(bAnimContext *UNUSED(ac), bAnimListElem *ale)
/* Main call to be exported to animation editors */
void ANIM_sync_animchannels_to_data(const bContext *C)
{
- bAnimContext ac;
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- bActionGroup *active_agrp = NULL;
- FCurve *active_fcurve = NULL;
-
- /* get animation context info for filtering the channels */
- if (ANIM_animdata_get_context(C, &ac) == 0)
- return;
-
- /* filter data */
- /* NOTE: we want all channels, since we want to be able to set selection status on some of them even when collapsed
- * However, don't include duplicates so that selection statuses don't override each other
- */
- filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS;
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- /* flush settings as appropriate depending on the types of the channels */
- for (ale = anim_data.first; ale; ale = ale->next) {
- switch (ale->type) {
- case ANIMTYPE_GROUP:
- animchan_sync_group(&ac, ale, &active_agrp);
- break;
-
- case ANIMTYPE_FCURVE:
- animchan_sync_fcurve(&ac, ale, &active_fcurve);
- break;
-
- case ANIMTYPE_GPLAYER:
- animchan_sync_gplayer(&ac, ale);
- break;
- }
- }
-
- ANIM_animdata_freelist(&anim_data);
+ bAnimContext ac;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ bActionGroup *active_agrp = NULL;
+ FCurve *active_fcurve = NULL;
+
+ /* get animation context info for filtering the channels */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return;
+
+ /* filter data */
+ /* NOTE: we want all channels, since we want to be able to set selection status on some of them even when collapsed
+ * However, don't include duplicates so that selection statuses don't override each other
+ */
+ filter = ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS;
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* flush settings as appropriate depending on the types of the channels */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ switch (ale->type) {
+ case ANIMTYPE_GROUP:
+ animchan_sync_group(&ac, ale, &active_agrp);
+ break;
+
+ case ANIMTYPE_FCURVE:
+ animchan_sync_fcurve(&ac, ale, &active_fcurve);
+ break;
+
+ case ANIMTYPE_GPLAYER:
+ animchan_sync_gplayer(&ac, ale);
+ break;
+ }
+ }
+
+ ANIM_animdata_freelist(&anim_data);
}
void ANIM_animdata_update(bAnimContext *ac, ListBase *anim_data)
{
- bAnimListElem *ale;
+ bAnimListElem *ale;
- if (ELEM(ac->datatype, ANIMCONT_MASK)) {
+ if (ELEM(ac->datatype, ANIMCONT_MASK)) {
#ifdef DEBUG
- /* quiet assert */
- for (ale = anim_data->first; ale; ale = ale->next) {
- ale->update = 0;
- }
+ /* quiet assert */
+ for (ale = anim_data->first; ale; ale = ale->next) {
+ ale->update = 0;
+ }
#endif
- return;
- }
-
- for (ale = anim_data->first; ale; ale = ale->next) {
- if (ale->type == ANIMTYPE_GPLAYER) {
- bGPDlayer *gpl = ale->data;
-
- if (ale->update & ANIM_UPDATE_ORDER) {
- ale->update &= ~ANIM_UPDATE_ORDER;
- if (gpl) {
- //gpencil_sort_frames(gpl);
- }
- }
-
- if (ale->update & ANIM_UPDATE_DEPS) {
- ale->update &= ~ANIM_UPDATE_DEPS;
- ANIM_list_elem_update(ac->bmain, ac->scene, ale);
- }
- /* disable handles to avoid crash */
- if (ale->update & ANIM_UPDATE_HANDLES) {
- ale->update &= ~ANIM_UPDATE_HANDLES;
- }
- }
- else if (ale->datatype == ALE_FCURVE) {
- FCurve *fcu = ale->key_data;
-
- if (ale->update & ANIM_UPDATE_ORDER) {
- ale->update &= ~ANIM_UPDATE_ORDER;
- if (fcu)
- sort_time_fcurve(fcu);
- }
-
- if (ale->update & ANIM_UPDATE_HANDLES) {
- ale->update &= ~ANIM_UPDATE_HANDLES;
- if (fcu)
- calchandles_fcurve(fcu);
- }
-
- if (ale->update & ANIM_UPDATE_DEPS) {
- ale->update &= ~ANIM_UPDATE_DEPS;
- ANIM_list_elem_update(ac->bmain, ac->scene, ale);
- }
- }
- else if (ELEM(ale->type, ANIMTYPE_ANIMDATA, ANIMTYPE_NLAACTION, ANIMTYPE_NLATRACK, ANIMTYPE_NLACURVE)) {
- if (ale->update & ANIM_UPDATE_DEPS) {
- ale->update &= ~ANIM_UPDATE_DEPS;
- ANIM_list_elem_update(ac->bmain, ac->scene, ale);
- }
- }
- else if (ale->update) {
+ return;
+ }
+
+ for (ale = anim_data->first; ale; ale = ale->next) {
+ if (ale->type == ANIMTYPE_GPLAYER) {
+ bGPDlayer *gpl = ale->data;
+
+ if (ale->update & ANIM_UPDATE_ORDER) {
+ ale->update &= ~ANIM_UPDATE_ORDER;
+ if (gpl) {
+ //gpencil_sort_frames(gpl);
+ }
+ }
+
+ if (ale->update & ANIM_UPDATE_DEPS) {
+ ale->update &= ~ANIM_UPDATE_DEPS;
+ ANIM_list_elem_update(ac->bmain, ac->scene, ale);
+ }
+ /* disable handles to avoid crash */
+ if (ale->update & ANIM_UPDATE_HANDLES) {
+ ale->update &= ~ANIM_UPDATE_HANDLES;
+ }
+ }
+ else if (ale->datatype == ALE_FCURVE) {
+ FCurve *fcu = ale->key_data;
+
+ if (ale->update & ANIM_UPDATE_ORDER) {
+ ale->update &= ~ANIM_UPDATE_ORDER;
+ if (fcu)
+ sort_time_fcurve(fcu);
+ }
+
+ if (ale->update & ANIM_UPDATE_HANDLES) {
+ ale->update &= ~ANIM_UPDATE_HANDLES;
+ if (fcu)
+ calchandles_fcurve(fcu);
+ }
+
+ if (ale->update & ANIM_UPDATE_DEPS) {
+ ale->update &= ~ANIM_UPDATE_DEPS;
+ ANIM_list_elem_update(ac->bmain, ac->scene, ale);
+ }
+ }
+ else if (ELEM(ale->type,
+ ANIMTYPE_ANIMDATA,
+ ANIMTYPE_NLAACTION,
+ ANIMTYPE_NLATRACK,
+ ANIMTYPE_NLACURVE)) {
+ if (ale->update & ANIM_UPDATE_DEPS) {
+ ale->update &= ~ANIM_UPDATE_DEPS;
+ ANIM_list_elem_update(ac->bmain, ac->scene, ale);
+ }
+ }
+ else if (ale->update) {
#if 0
- if (G.debug & G_DEBUG) {
- printf("%s: Unhandled animchannel updates (%d) for type=%d (%p)\n",
- __func__, ale->update, ale->type, ale->data);
- }
+ if (G.debug & G_DEBUG) {
+ printf("%s: Unhandled animchannel updates (%d) for type=%d (%p)\n",
+ __func__, ale->update, ale->type, ale->data);
+ }
#endif
- /* Prevent crashes in cases where it can't be handled */
- ale->update = 0;
- }
+ /* Prevent crashes in cases where it can't be handled */
+ ale->update = 0;
+ }
- BLI_assert(ale->update == 0);
- }
+ BLI_assert(ale->update == 0);
+ }
}
void ANIM_animdata_freelist(ListBase *anim_data)
{
#ifndef NDEBUG
- bAnimListElem *ale, *ale_next;
- for (ale = anim_data->first; ale; ale = ale_next) {
- ale_next = ale->next;
- BLI_assert(ale->update == 0);
- MEM_freeN(ale);
- }
- BLI_listbase_clear(anim_data);
+ bAnimListElem *ale, *ale_next;
+ for (ale = anim_data->first; ale; ale = ale_next) {
+ ale_next = ale->next;
+ BLI_assert(ale->update == 0);
+ MEM_freeN(ale);
+ }
+ BLI_listbase_clear(anim_data);
#else
- BLI_freelistN(anim_data);
+ BLI_freelistN(anim_data);
#endif
}
diff --git a/source/blender/editors/animation/anim_draw.c b/source/blender/editors/animation/anim_draw.c
index 2b168aa9463..11c768a8efd 100644
--- a/source/blender/editors/animation/anim_draw.c
+++ b/source/blender/editors/animation/anim_draw.c
@@ -65,88 +65,87 @@
/* Draw current frame number in a little green box beside the current frame indicator */
void ANIM_draw_cfra_number(const bContext *C, View2D *v2d, short flag)
{
- Scene *scene = CTX_data_scene(C);
- const float time = scene->r.cfra + scene->r.subframe;
- const float cfra = (float)(time * scene->r.framelen);
- const bool show_time = (flag & DRAWCFRA_UNIT_SECONDS) != 0;
-
- const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- unsigned char col[4];
- float color[4];
- float xscale, x, y;
- char numstr[32] = " t "; /* t is the character to start replacing from */
- float hlen;
- int slen;
-
- /* because the frame number text is subject to the same scaling as the contents of the view */
- UI_view2d_scale_get(v2d, &xscale, NULL);
- GPU_matrix_push();
- GPU_matrix_scale_2f(1.0f / xscale, 1.0f);
-
- /* get timecode string
- * - padding on str-buf passed so that it doesn't sit on the frame indicator
- */
- if (show_time) {
- BLI_timecode_string_from_time(&numstr[2], sizeof(numstr) - 2, 0, FRA2TIME(cfra), FPS, U.timecode_style);
- }
- else {
- BLI_timecode_string_from_time_seconds(&numstr[2], sizeof(numstr) - 2, 1, cfra);
- }
-
- slen = UI_fontstyle_string_width(fstyle, numstr) - 1;
- hlen = slen * 0.5f;
-
- /* get starting coordinates for drawing */
- x = cfra * xscale;
- y = -0.1f * U.widget_unit;
-
- /* draw green box around/behind text */
- UI_GetThemeColor4fv(TH_CFRAME, color);
- color[3] = 3.0f;
-
- UI_draw_roundbox_corner_set(UI_CNR_ALL);
- UI_draw_roundbox_aa(true,
- x - hlen - 0.1f * U.widget_unit,
- y + 3.0f,
- x + hlen + 0.1f * U.widget_unit,
- y -3.0f + U.widget_unit,
- 0.1f * U.widget_unit,
- color);
-
- /* draw current frame number */
- UI_GetThemeColor4ubv(TH_TEXT_HI, col);
- UI_fontstyle_draw_simple(fstyle,
- x - hlen - 0.15f * U.widget_unit,
- y + 0.28f * U.widget_unit,
- numstr, col);
-
- /* restore view transform */
- GPU_matrix_pop();
+ Scene *scene = CTX_data_scene(C);
+ const float time = scene->r.cfra + scene->r.subframe;
+ const float cfra = (float)(time * scene->r.framelen);
+ const bool show_time = (flag & DRAWCFRA_UNIT_SECONDS) != 0;
+
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ unsigned char col[4];
+ float color[4];
+ float xscale, x, y;
+ char numstr[32] = " t "; /* t is the character to start replacing from */
+ float hlen;
+ int slen;
+
+ /* because the frame number text is subject to the same scaling as the contents of the view */
+ UI_view2d_scale_get(v2d, &xscale, NULL);
+ GPU_matrix_push();
+ GPU_matrix_scale_2f(1.0f / xscale, 1.0f);
+
+ /* get timecode string
+ * - padding on str-buf passed so that it doesn't sit on the frame indicator
+ */
+ if (show_time) {
+ BLI_timecode_string_from_time(
+ &numstr[2], sizeof(numstr) - 2, 0, FRA2TIME(cfra), FPS, U.timecode_style);
+ }
+ else {
+ BLI_timecode_string_from_time_seconds(&numstr[2], sizeof(numstr) - 2, 1, cfra);
+ }
+
+ slen = UI_fontstyle_string_width(fstyle, numstr) - 1;
+ hlen = slen * 0.5f;
+
+ /* get starting coordinates for drawing */
+ x = cfra * xscale;
+ y = -0.1f * U.widget_unit;
+
+ /* draw green box around/behind text */
+ UI_GetThemeColor4fv(TH_CFRAME, color);
+ color[3] = 3.0f;
+
+ UI_draw_roundbox_corner_set(UI_CNR_ALL);
+ UI_draw_roundbox_aa(true,
+ x - hlen - 0.1f * U.widget_unit,
+ y + 3.0f,
+ x + hlen + 0.1f * U.widget_unit,
+ y - 3.0f + U.widget_unit,
+ 0.1f * U.widget_unit,
+ color);
+
+ /* draw current frame number */
+ UI_GetThemeColor4ubv(TH_TEXT_HI, col);
+ UI_fontstyle_draw_simple(
+ fstyle, x - hlen - 0.15f * U.widget_unit, y + 0.28f * U.widget_unit, numstr, col);
+
+ /* restore view transform */
+ GPU_matrix_pop();
}
/* General call for drawing current frame indicator in animation editor */
void ANIM_draw_cfra(const bContext *C, View2D *v2d, short flag)
{
- Scene *scene = CTX_data_scene(C);
+ Scene *scene = CTX_data_scene(C);
- const float time = scene->r.cfra + scene->r.subframe;
- const float x = (float)(time * scene->r.framelen);
+ const float time = scene->r.cfra + scene->r.subframe;
+ const float x = (float)(time * scene->r.framelen);
- GPU_line_width((flag & DRAWCFRA_WIDE) ? 3.0 : 2.0);
+ GPU_line_width((flag & DRAWCFRA_WIDE) ? 3.0 : 2.0);
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- /* Draw a light green line to indicate current frame */
- immUniformThemeColor(TH_CFRAME);
+ /* Draw a light green line to indicate current frame */
+ immUniformThemeColor(TH_CFRAME);
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, x, v2d->cur.ymin - 500.0f); /* XXX arbitrary... want it go to bottom */
- immVertex2f(pos, x, v2d->cur.ymax);
- immEnd();
- immUnbindProgram();
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, x, v2d->cur.ymin - 500.0f); /* XXX arbitrary... want it go to bottom */
+ immVertex2f(pos, x, v2d->cur.ymax);
+ immEnd();
+ immUnbindProgram();
}
/* *************************************************** */
@@ -156,34 +155,35 @@ void ANIM_draw_cfra(const bContext *C, View2D *v2d, short flag)
/* Draw preview range 'curtains' for highlighting where the animation data is */
void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width)
{
- Scene *scene = CTX_data_scene(C);
-
- /* only draw this if preview range is set */
- if (PRVRANGEON) {
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
-
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
-
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformThemeColorShadeAlpha(TH_ANIM_PREVIEW_RANGE, -25, -30);
- /* XXX: Fix this hardcoded color (anim_active) */
- //immUniformColor4f(0.8f, 0.44f, 0.1f, 0.2f);
-
- /* only draw two separate 'curtains' if there's no overlap between them */
- if (PSFRA < PEFRA + end_frame_width) {
- immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax);
- immRectf(pos, (float)(PEFRA + end_frame_width), v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
- }
- else {
- immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
- }
-
- immUnbindProgram();
-
- GPU_blend(false);
- }
+ Scene *scene = CTX_data_scene(C);
+
+ /* only draw this if preview range is set */
+ if (PRVRANGEON) {
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColorShadeAlpha(TH_ANIM_PREVIEW_RANGE, -25, -30);
+ /* XXX: Fix this hardcoded color (anim_active) */
+ //immUniformColor4f(0.8f, 0.44f, 0.1f, 0.2f);
+
+ /* only draw two separate 'curtains' if there's no overlap between them */
+ if (PSFRA < PEFRA + end_frame_width) {
+ immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, (float)PSFRA, v2d->cur.ymax);
+ immRectf(pos, (float)(PEFRA + end_frame_width), v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
+ }
+ else {
+ immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
+ }
+
+ immUnbindProgram();
+
+ GPU_blend(false);
+ }
}
/* *************************************************** */
@@ -193,39 +193,40 @@ void ANIM_draw_previewrange(const bContext *C, View2D *v2d, int end_frame_width)
// TODO: Should we still show these when preview range is enabled?
void ANIM_draw_framerange(Scene *scene, View2D *v2d)
{
- /* draw darkened area outside of active timeline frame range */
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- GPU_blend(true);
+ /* draw darkened area outside of active timeline frame range */
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
- immUniformThemeColorShadeAlpha(TH_BACK, -25, -100);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+ immUniformThemeColorShadeAlpha(TH_BACK, -25, -100);
- if (SFRA < EFRA) {
- immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax);
- immRectf(pos, (float)EFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
- }
- else {
- immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
- }
+ if (SFRA < EFRA) {
+ immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, (float)SFRA, v2d->cur.ymax);
+ immRectf(pos, (float)EFRA, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
+ }
+ else {
+ immRectf(pos, v2d->cur.xmin, v2d->cur.ymin, v2d->cur.xmax, v2d->cur.ymax);
+ }
- GPU_blend(false);
+ GPU_blend(false);
- /* thin lines where the actual frames are */
- immUniformThemeColorShade(TH_BACK, -60);
+ /* thin lines where the actual frames are */
+ immUniformThemeColorShade(TH_BACK, -60);
- immBegin(GPU_PRIM_LINES, 4);
+ immBegin(GPU_PRIM_LINES, 4);
- immVertex2f(pos, (float)SFRA, v2d->cur.ymin);
- immVertex2f(pos, (float)SFRA, v2d->cur.ymax);
+ immVertex2f(pos, (float)SFRA, v2d->cur.ymin);
+ immVertex2f(pos, (float)SFRA, v2d->cur.ymax);
- immVertex2f(pos, (float)EFRA, v2d->cur.ymin);
- immVertex2f(pos, (float)EFRA, v2d->cur.ymax);
+ immVertex2f(pos, (float)EFRA, v2d->cur.ymin);
+ immVertex2f(pos, (float)EFRA, v2d->cur.ymax);
- immEnd();
- immUnbindProgram();
+ immEnd();
+ immUnbindProgram();
}
/* *************************************************** */
@@ -235,28 +236,33 @@ void ANIM_draw_framerange(Scene *scene, View2D *v2d)
// TODO: do not supply return this if the animdata tells us that there is no mapping to perform
AnimData *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale)
{
- /* sanity checks */
- if (ac == NULL)
- return NULL;
-
- /* abort if rendering - we may get some race condition issues... */
- if (G.is_rendering) return NULL;
-
- /* apart from strictly keyframe-related contexts, this shouldn't even happen */
- // XXX: nla and channel here may not be necessary...
- if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_SHAPEKEY, ANIMCONT_DOPESHEET,
- ANIMCONT_FCURVES, ANIMCONT_NLA, ANIMCONT_CHANNEL))
- {
- /* handling depends on the type of animation-context we've got */
- if (ale) {
- /* NLA Control Curves occur on NLA strips, and shouldn't be subjected to this kind of mapping */
- if (ale->type != ANIMTYPE_NLACURVE)
- return ale->adt;
- }
- }
-
- /* cannot handle... */
- return NULL;
+ /* sanity checks */
+ if (ac == NULL)
+ return NULL;
+
+ /* abort if rendering - we may get some race condition issues... */
+ if (G.is_rendering)
+ return NULL;
+
+ /* apart from strictly keyframe-related contexts, this shouldn't even happen */
+ // XXX: nla and channel here may not be necessary...
+ if (ELEM(ac->datatype,
+ ANIMCONT_ACTION,
+ ANIMCONT_SHAPEKEY,
+ ANIMCONT_DOPESHEET,
+ ANIMCONT_FCURVES,
+ ANIMCONT_NLA,
+ ANIMCONT_CHANNEL)) {
+ /* handling depends on the type of animation-context we've got */
+ if (ale) {
+ /* NLA Control Curves occur on NLA strips, and shouldn't be subjected to this kind of mapping */
+ if (ale->type != ANIMTYPE_NLACURVE)
+ return ale->adt;
+ }
+ }
+
+ /* cannot handle... */
+ return NULL;
}
/* ------------------- */
@@ -264,65 +270,64 @@ AnimData *ANIM_nla_mapping_get(bAnimContext *ac, bAnimListElem *ale)
/* helper function for ANIM_nla_mapping_apply_fcurve() -> "restore", i.e. mapping points back to action-time */
static short bezt_nlamapping_restore(KeyframeEditData *ked, BezTriple *bezt)
{
- /* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */
- AnimData *adt = (AnimData *)ked->data;
- short only_keys = (short)ked->i1;
+ /* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */
+ AnimData *adt = (AnimData *)ked->data;
+ short only_keys = (short)ked->i1;
- /* adjust BezTriple handles only if allowed to */
- if (only_keys == 0) {
- bezt->vec[0][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[0][0], NLATIME_CONVERT_UNMAP);
- bezt->vec[2][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[2][0], NLATIME_CONVERT_UNMAP);
- }
+ /* adjust BezTriple handles only if allowed to */
+ if (only_keys == 0) {
+ bezt->vec[0][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[0][0], NLATIME_CONVERT_UNMAP);
+ bezt->vec[2][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[2][0], NLATIME_CONVERT_UNMAP);
+ }
- bezt->vec[1][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[1][0], NLATIME_CONVERT_UNMAP);
+ bezt->vec[1][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[1][0], NLATIME_CONVERT_UNMAP);
- return 0;
+ return 0;
}
/* helper function for ANIM_nla_mapping_apply_fcurve() -> "apply",
* i.e. mapping points to NLA-mapped global time */
static short bezt_nlamapping_apply(KeyframeEditData *ked, BezTriple *bezt)
{
- /* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */
- AnimData *adt = (AnimData *)ked->data;
- short only_keys = (short)ked->i1;
+ /* AnimData block providing scaling is stored in 'data', only_keys option is stored in i1 */
+ AnimData *adt = (AnimData *)ked->data;
+ short only_keys = (short)ked->i1;
- /* adjust BezTriple handles only if allowed to */
- if (only_keys == 0) {
- bezt->vec[0][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[0][0], NLATIME_CONVERT_MAP);
- bezt->vec[2][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[2][0], NLATIME_CONVERT_MAP);
- }
+ /* adjust BezTriple handles only if allowed to */
+ if (only_keys == 0) {
+ bezt->vec[0][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[0][0], NLATIME_CONVERT_MAP);
+ bezt->vec[2][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[2][0], NLATIME_CONVERT_MAP);
+ }
- bezt->vec[1][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[1][0], NLATIME_CONVERT_MAP);
+ bezt->vec[1][0] = BKE_nla_tweakedit_remap(adt, bezt->vec[1][0], NLATIME_CONVERT_MAP);
- return 0;
+ return 0;
}
-
/* Apply/Unapply NLA mapping to all keyframes in the nominated F-Curve
* - restore = whether to map points back to non-mapped time
* - only_keys = whether to only adjust the location of the center point of beztriples
*/
void ANIM_nla_mapping_apply_fcurve(AnimData *adt, FCurve *fcu, bool restore, bool only_keys)
{
- KeyframeEditData ked = {{NULL}};
- KeyframeEditFunc map_cb;
-
- /* init edit data
- * - AnimData is stored in 'data'
- * - only_keys is stored in 'i1'
- */
- ked.data = (void *)adt;
- ked.i1 = (int)only_keys;
-
- /* get editing callback */
- if (restore)
- map_cb = bezt_nlamapping_restore;
- else
- map_cb = bezt_nlamapping_apply;
-
- /* apply to F-Curve */
- ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, map_cb, NULL);
+ KeyframeEditData ked = {{NULL}};
+ KeyframeEditFunc map_cb;
+
+ /* init edit data
+ * - AnimData is stored in 'data'
+ * - only_keys is stored in 'i1'
+ */
+ ked.data = (void *)adt;
+ ked.i1 = (int)only_keys;
+
+ /* get editing callback */
+ if (restore)
+ map_cb = bezt_nlamapping_restore;
+ else
+ map_cb = bezt_nlamapping_apply;
+
+ /* apply to F-Curve */
+ ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, map_cb, NULL);
}
/* *************************************************** */
@@ -331,329 +336,328 @@ void ANIM_nla_mapping_apply_fcurve(AnimData *adt, FCurve *fcu, bool restore, boo
/* Get flags used for normalization in ANIM_unit_mapping_get_factor. */
short ANIM_get_normalization_flags(bAnimContext *ac)
{
- if (ac->sl->spacetype == SPACE_GRAPH) {
- SpaceGraph *sipo = (SpaceGraph *) ac->sl;
- bool use_normalization = (sipo->flag & SIPO_NORMALIZE) != 0;
- bool freeze_normalization = (sipo->flag & SIPO_NORMALIZE_FREEZE) != 0;
- return use_normalization
- ? (ANIM_UNITCONV_NORMALIZE | (freeze_normalization ? ANIM_UNITCONV_NORMALIZE_FREEZE : 0))
- : 0;
- }
-
- return 0;
+ if (ac->sl->spacetype == SPACE_GRAPH) {
+ SpaceGraph *sipo = (SpaceGraph *)ac->sl;
+ bool use_normalization = (sipo->flag & SIPO_NORMALIZE) != 0;
+ bool freeze_normalization = (sipo->flag & SIPO_NORMALIZE_FREEZE) != 0;
+ return use_normalization ? (ANIM_UNITCONV_NORMALIZE |
+ (freeze_normalization ? ANIM_UNITCONV_NORMALIZE_FREEZE : 0)) :
+ 0;
+ }
+
+ return 0;
}
static float normalization_factor_get(Scene *scene, FCurve *fcu, short flag, float *r_offset)
{
- float factor = 1.0f, offset = 0.0f;
-
- if (flag & ANIM_UNITCONV_RESTORE) {
- if (r_offset)
- *r_offset = fcu->prev_offset;
-
- return 1.0f / fcu->prev_norm_factor;
- }
-
- if (flag & ANIM_UNITCONV_NORMALIZE_FREEZE) {
- if (r_offset)
- *r_offset = fcu->prev_offset;
- if (fcu->prev_norm_factor == 0.0f) {
- /* Happens when Auto Normalize was disabled before
- * any curves were displayed.
- */
- return 1.0f;
- }
- return fcu->prev_norm_factor;
- }
-
- if (G.moving & G_TRANSFORM_FCURVES) {
- if (r_offset)
- *r_offset = fcu->prev_offset;
- if (fcu->prev_norm_factor == 0.0f) {
- /* Same as above. */
- return 1.0f;
- }
- return fcu->prev_norm_factor;
- }
-
- fcu->prev_norm_factor = 1.0f;
- if (fcu->bezt) {
- const bool use_preview_only = PRVRANGEON;
- const BezTriple *bezt;
- int i;
- float max_coord = -FLT_MAX;
- float min_coord = FLT_MAX;
- float range;
-
- if (fcu->totvert < 1) {
- return 1.0f;
- }
-
- for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
- if (use_preview_only && !IN_RANGE_INCL(bezt->vec[1][0],
- scene->r.psfra,
- scene->r.pefra))
- {
- continue;
- }
-
- if (i == 0) {
- /* We ignore extrapolation flags and handle here, and use the
- * control point position only. so we normalize "interesting"
- * part of the curve.
- *
- * Here we handle left extrapolation.
- */
- max_coord = max_ff(max_coord, bezt->vec[1][1]);
-
- min_coord = min_ff(min_coord, bezt->vec[1][1]);
- }
- else {
- const BezTriple *prev_bezt = bezt - 1;
- if (prev_bezt->ipo == BEZT_IPO_CONST) {
- /* Constant interpolation: previous CV value is used up
- * to the current keyframe.
- */
- max_coord = max_ff(max_coord, bezt->vec[1][1]);
- min_coord = min_ff(min_coord, bezt->vec[1][1]);
- }
- else if (prev_bezt->ipo == BEZT_IPO_LIN) {
- /* Linear interpolation: min/max using both previous and
- * and current CV.
- */
- max_coord = max_ff(max_coord, bezt->vec[1][1]);
- min_coord = min_ff(min_coord, bezt->vec[1][1]);
- max_coord = max_ff(max_coord, prev_bezt->vec[1][1]);
- min_coord = min_ff(min_coord, prev_bezt->vec[1][1]);
- }
- else if (prev_bezt->ipo == BEZT_IPO_BEZ) {
- const int resol = fcu->driver
- ? 32
- : min_ii((int)(5.0f * len_v2v2(bezt->vec[1], prev_bezt->vec[1])), 32);
- if (resol < 2) {
- max_coord = max_ff(max_coord, prev_bezt->vec[1][1]);
- min_coord = min_ff(min_coord, prev_bezt->vec[1][1]);
- }
- else {
- float data[120];
- float v1[2], v2[2], v3[2], v4[2];
-
- v1[0] = prev_bezt->vec[1][0];
- v1[1] = prev_bezt->vec[1][1];
- v2[0] = prev_bezt->vec[2][0];
- v2[1] = prev_bezt->vec[2][1];
-
- v3[0] = bezt->vec[0][0];
- v3[1] = bezt->vec[0][1];
- v4[0] = bezt->vec[1][0];
- v4[1] = bezt->vec[1][1];
-
- correct_bezpart(v1, v2, v3, v4);
-
- BKE_curve_forward_diff_bezier(v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float) * 3);
- BKE_curve_forward_diff_bezier(v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float) * 3);
-
- for (int j = 0; j <= resol; ++j) {
- const float *fp = &data[j * 3];
- max_coord = max_ff(max_coord, fp[1]);
- min_coord = min_ff(min_coord, fp[1]);
- }
- }
- }
- }
- }
-
- if (max_coord > min_coord) {
- range = max_coord - min_coord;
- if (range > FLT_EPSILON) {
- factor = 2.0f / range;
- }
- offset = -min_coord - range / 2.0f;
- }
- else if (max_coord == min_coord) {
- factor = 1.0f;
- offset = -min_coord;
- }
- }
- BLI_assert(factor != 0.0f);
- if (r_offset) {
- *r_offset = offset;
- }
-
- fcu->prev_norm_factor = factor;
- fcu->prev_offset = offset;
- return factor;
+ float factor = 1.0f, offset = 0.0f;
+
+ if (flag & ANIM_UNITCONV_RESTORE) {
+ if (r_offset)
+ *r_offset = fcu->prev_offset;
+
+ return 1.0f / fcu->prev_norm_factor;
+ }
+
+ if (flag & ANIM_UNITCONV_NORMALIZE_FREEZE) {
+ if (r_offset)
+ *r_offset = fcu->prev_offset;
+ if (fcu->prev_norm_factor == 0.0f) {
+ /* Happens when Auto Normalize was disabled before
+ * any curves were displayed.
+ */
+ return 1.0f;
+ }
+ return fcu->prev_norm_factor;
+ }
+
+ if (G.moving & G_TRANSFORM_FCURVES) {
+ if (r_offset)
+ *r_offset = fcu->prev_offset;
+ if (fcu->prev_norm_factor == 0.0f) {
+ /* Same as above. */
+ return 1.0f;
+ }
+ return fcu->prev_norm_factor;
+ }
+
+ fcu->prev_norm_factor = 1.0f;
+ if (fcu->bezt) {
+ const bool use_preview_only = PRVRANGEON;
+ const BezTriple *bezt;
+ int i;
+ float max_coord = -FLT_MAX;
+ float min_coord = FLT_MAX;
+ float range;
+
+ if (fcu->totvert < 1) {
+ return 1.0f;
+ }
+
+ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ if (use_preview_only && !IN_RANGE_INCL(bezt->vec[1][0], scene->r.psfra, scene->r.pefra)) {
+ continue;
+ }
+
+ if (i == 0) {
+ /* We ignore extrapolation flags and handle here, and use the
+ * control point position only. so we normalize "interesting"
+ * part of the curve.
+ *
+ * Here we handle left extrapolation.
+ */
+ max_coord = max_ff(max_coord, bezt->vec[1][1]);
+
+ min_coord = min_ff(min_coord, bezt->vec[1][1]);
+ }
+ else {
+ const BezTriple *prev_bezt = bezt - 1;
+ if (prev_bezt->ipo == BEZT_IPO_CONST) {
+ /* Constant interpolation: previous CV value is used up
+ * to the current keyframe.
+ */
+ max_coord = max_ff(max_coord, bezt->vec[1][1]);
+ min_coord = min_ff(min_coord, bezt->vec[1][1]);
+ }
+ else if (prev_bezt->ipo == BEZT_IPO_LIN) {
+ /* Linear interpolation: min/max using both previous and
+ * and current CV.
+ */
+ max_coord = max_ff(max_coord, bezt->vec[1][1]);
+ min_coord = min_ff(min_coord, bezt->vec[1][1]);
+ max_coord = max_ff(max_coord, prev_bezt->vec[1][1]);
+ min_coord = min_ff(min_coord, prev_bezt->vec[1][1]);
+ }
+ else if (prev_bezt->ipo == BEZT_IPO_BEZ) {
+ const int resol = fcu->driver ?
+ 32 :
+ min_ii((int)(5.0f * len_v2v2(bezt->vec[1], prev_bezt->vec[1])),
+ 32);
+ if (resol < 2) {
+ max_coord = max_ff(max_coord, prev_bezt->vec[1][1]);
+ min_coord = min_ff(min_coord, prev_bezt->vec[1][1]);
+ }
+ else {
+ float data[120];
+ float v1[2], v2[2], v3[2], v4[2];
+
+ v1[0] = prev_bezt->vec[1][0];
+ v1[1] = prev_bezt->vec[1][1];
+ v2[0] = prev_bezt->vec[2][0];
+ v2[1] = prev_bezt->vec[2][1];
+
+ v3[0] = bezt->vec[0][0];
+ v3[1] = bezt->vec[0][1];
+ v4[0] = bezt->vec[1][0];
+ v4[1] = bezt->vec[1][1];
+
+ correct_bezpart(v1, v2, v3, v4);
+
+ BKE_curve_forward_diff_bezier(
+ v1[0], v2[0], v3[0], v4[0], data, resol, sizeof(float) * 3);
+ BKE_curve_forward_diff_bezier(
+ v1[1], v2[1], v3[1], v4[1], data + 1, resol, sizeof(float) * 3);
+
+ for (int j = 0; j <= resol; ++j) {
+ const float *fp = &data[j * 3];
+ max_coord = max_ff(max_coord, fp[1]);
+ min_coord = min_ff(min_coord, fp[1]);
+ }
+ }
+ }
+ }
+ }
+
+ if (max_coord > min_coord) {
+ range = max_coord - min_coord;
+ if (range > FLT_EPSILON) {
+ factor = 2.0f / range;
+ }
+ offset = -min_coord - range / 2.0f;
+ }
+ else if (max_coord == min_coord) {
+ factor = 1.0f;
+ offset = -min_coord;
+ }
+ }
+ BLI_assert(factor != 0.0f);
+ if (r_offset) {
+ *r_offset = offset;
+ }
+
+ fcu->prev_norm_factor = factor;
+ fcu->prev_offset = offset;
+ return factor;
}
/* Get unit conversion factor for given ID + F-Curve */
float ANIM_unit_mapping_get_factor(Scene *scene, ID *id, FCurve *fcu, short flag, float *r_offset)
{
- if (flag & ANIM_UNITCONV_NORMALIZE) {
- return normalization_factor_get(scene, fcu, flag, r_offset);
- }
-
- if (r_offset)
- *r_offset = 0.0f;
-
- /* sanity checks */
- if (id && fcu && fcu->rna_path) {
- PointerRNA ptr, id_ptr;
- PropertyRNA *prop;
-
- /* get RNA property that F-Curve affects */
- RNA_id_pointer_create(id, &id_ptr);
- if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
- /* rotations: radians <-> degrees? */
- if (RNA_SUBTYPE_UNIT(RNA_property_subtype(prop)) == PROP_UNIT_ROTATION) {
- /* if the radians flag is not set, default to using degrees which need conversions */
- if ((scene) && (scene->unit.system_rotation == USER_UNIT_ROT_RADIANS) == 0) {
- if (flag & ANIM_UNITCONV_RESTORE)
- return DEG2RADF(1.0f); /* degrees to radians */
- else
- return RAD2DEGF(1.0f); /* radians to degrees */
- }
- }
-
- /* TODO: other rotation types here as necessary */
- }
- }
-
- /* no mapping needs to occur... */
- return 1.0f;
+ if (flag & ANIM_UNITCONV_NORMALIZE) {
+ return normalization_factor_get(scene, fcu, flag, r_offset);
+ }
+
+ if (r_offset)
+ *r_offset = 0.0f;
+
+ /* sanity checks */
+ if (id && fcu && fcu->rna_path) {
+ PointerRNA ptr, id_ptr;
+ PropertyRNA *prop;
+
+ /* get RNA property that F-Curve affects */
+ RNA_id_pointer_create(id, &id_ptr);
+ if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
+ /* rotations: radians <-> degrees? */
+ if (RNA_SUBTYPE_UNIT(RNA_property_subtype(prop)) == PROP_UNIT_ROTATION) {
+ /* if the radians flag is not set, default to using degrees which need conversions */
+ if ((scene) && (scene->unit.system_rotation == USER_UNIT_ROT_RADIANS) == 0) {
+ if (flag & ANIM_UNITCONV_RESTORE)
+ return DEG2RADF(1.0f); /* degrees to radians */
+ else
+ return RAD2DEGF(1.0f); /* radians to degrees */
+ }
+ }
+
+ /* TODO: other rotation types here as necessary */
+ }
+ }
+
+ /* no mapping needs to occur... */
+ return 1.0f;
}
static bool find_prev_next_keyframes(struct bContext *C, int *nextfra, int *prevfra)
{
- Scene *scene = CTX_data_scene(C);
- Object *ob = CTX_data_active_object(C);
- Mask *mask = CTX_data_edit_mask(C);
- bDopeSheet ads = {NULL};
- DLRBT_Tree keys;
- ActKeyColumn *aknext, *akprev;
- float cfranext, cfraprev;
- bool donenext = false, doneprev = false;
- int nextcount = 0, prevcount = 0;
-
- cfranext = cfraprev = (float)(CFRA);
-
- /* init binarytree-list for getting keyframes */
- BLI_dlrbTree_init(&keys);
-
- /* seed up dummy dopesheet context with flags to perform necessary filtering */
- if ((scene->flag & SCE_KEYS_NO_SELONLY) == 0) {
- /* only selected channels are included */
- ads.filterflag |= ADS_FILTER_ONLYSEL;
- }
-
- /* populate tree with keyframe nodes */
- scene_to_keylist(&ads, scene, &keys, 0);
- gpencil_to_keylist(&ads, scene->gpd, &keys, false);
-
- if (ob) {
- ob_to_keylist(&ads, ob, &keys, 0);
- gpencil_to_keylist(&ads, ob->data, &keys, false);
- }
-
- if (mask) {
- MaskLayer *masklay = BKE_mask_layer_active(mask);
- mask_to_keylist(&ads, masklay, &keys);
- }
-
- /* find matching keyframe in the right direction */
- do {
- aknext = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &cfranext);
-
- if (aknext) {
- if (CFRA == (int)aknext->cfra) {
- /* make this the new starting point for the search and ignore */
- cfranext = aknext->cfra;
- }
- else {
- /* this changes the frame, so set the frame and we're done */
- if (++nextcount == U.view_frame_keyframes)
- donenext = true;
- }
- cfranext = aknext->cfra;
- }
- } while ((aknext != NULL) && (donenext == false));
-
- do {
- akprev = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &cfraprev);
-
- if (akprev) {
- if (CFRA == (int)akprev->cfra) {
- /* make this the new starting point for the search */
- }
- else {
- /* this changes the frame, so set the frame and we're done */
- if (++prevcount == U.view_frame_keyframes)
- doneprev = true;
- }
- cfraprev = akprev->cfra;
- }
- } while ((akprev != NULL) && (doneprev == false));
-
- /* free temp stuff */
- BLI_dlrbTree_free(&keys);
-
- /* any success? */
- if (doneprev || donenext) {
- if (doneprev)
- *prevfra = cfraprev;
- else
- *prevfra = CFRA - (cfranext - CFRA);
-
- if (donenext)
- *nextfra = cfranext;
- else
- *nextfra = CFRA + (CFRA - cfraprev);
-
- return true;
- }
-
- return false;
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ Mask *mask = CTX_data_edit_mask(C);
+ bDopeSheet ads = {NULL};
+ DLRBT_Tree keys;
+ ActKeyColumn *aknext, *akprev;
+ float cfranext, cfraprev;
+ bool donenext = false, doneprev = false;
+ int nextcount = 0, prevcount = 0;
+
+ cfranext = cfraprev = (float)(CFRA);
+
+ /* init binarytree-list for getting keyframes */
+ BLI_dlrbTree_init(&keys);
+
+ /* seed up dummy dopesheet context with flags to perform necessary filtering */
+ if ((scene->flag & SCE_KEYS_NO_SELONLY) == 0) {
+ /* only selected channels are included */
+ ads.filterflag |= ADS_FILTER_ONLYSEL;
+ }
+
+ /* populate tree with keyframe nodes */
+ scene_to_keylist(&ads, scene, &keys, 0);
+ gpencil_to_keylist(&ads, scene->gpd, &keys, false);
+
+ if (ob) {
+ ob_to_keylist(&ads, ob, &keys, 0);
+ gpencil_to_keylist(&ads, ob->data, &keys, false);
+ }
+
+ if (mask) {
+ MaskLayer *masklay = BKE_mask_layer_active(mask);
+ mask_to_keylist(&ads, masklay, &keys);
+ }
+
+ /* find matching keyframe in the right direction */
+ do {
+ aknext = (ActKeyColumn *)BLI_dlrbTree_search_next(&keys, compare_ak_cfraPtr, &cfranext);
+
+ if (aknext) {
+ if (CFRA == (int)aknext->cfra) {
+ /* make this the new starting point for the search and ignore */
+ cfranext = aknext->cfra;
+ }
+ else {
+ /* this changes the frame, so set the frame and we're done */
+ if (++nextcount == U.view_frame_keyframes)
+ donenext = true;
+ }
+ cfranext = aknext->cfra;
+ }
+ } while ((aknext != NULL) && (donenext == false));
+
+ do {
+ akprev = (ActKeyColumn *)BLI_dlrbTree_search_prev(&keys, compare_ak_cfraPtr, &cfraprev);
+
+ if (akprev) {
+ if (CFRA == (int)akprev->cfra) {
+ /* make this the new starting point for the search */
+ }
+ else {
+ /* this changes the frame, so set the frame and we're done */
+ if (++prevcount == U.view_frame_keyframes)
+ doneprev = true;
+ }
+ cfraprev = akprev->cfra;
+ }
+ } while ((akprev != NULL) && (doneprev == false));
+
+ /* free temp stuff */
+ BLI_dlrbTree_free(&keys);
+
+ /* any success? */
+ if (doneprev || donenext) {
+ if (doneprev)
+ *prevfra = cfraprev;
+ else
+ *prevfra = CFRA - (cfranext - CFRA);
+
+ if (donenext)
+ *nextfra = cfranext;
+ else
+ *nextfra = CFRA + (CFRA - cfraprev);
+
+ return true;
+ }
+
+ return false;
}
void ANIM_center_frame(struct bContext *C, int smooth_viewtx)
{
- ARegion *ar = CTX_wm_region(C);
- Scene *scene = CTX_data_scene(C);
- float w = BLI_rctf_size_x(&ar->v2d.cur);
- rctf newrct;
- int nextfra, prevfra;
-
- switch (U.view_frame_type) {
- case ZOOM_FRAME_MODE_SECONDS:
- {
- const float fps = FPS;
- newrct.xmax = scene->r.cfra + U.view_frame_seconds * fps + 1;
- newrct.xmin = scene->r.cfra - U.view_frame_seconds * fps - 1;
- newrct.ymax = ar->v2d.cur.ymax;
- newrct.ymin = ar->v2d.cur.ymin;
- break;
- }
-
- /* hardest case of all, look for all keyframes around frame and display those */
- case ZOOM_FRAME_MODE_KEYFRAMES:
- if (find_prev_next_keyframes(C, &nextfra, &prevfra)) {
- newrct.xmax = nextfra;
- newrct.xmin = prevfra;
- newrct.ymax = ar->v2d.cur.ymax;
- newrct.ymin = ar->v2d.cur.ymin;
- break;
- }
- /* else drop through, keep range instead */
- ATTR_FALLTHROUGH;
-
- case ZOOM_FRAME_MODE_KEEP_RANGE:
- default:
- newrct.xmax = scene->r.cfra + (w / 2);
- newrct.xmin = scene->r.cfra - (w / 2);
- newrct.ymax = ar->v2d.cur.ymax;
- newrct.ymin = ar->v2d.cur.ymin;
- break;
- }
-
- UI_view2d_smooth_view(C, ar, &newrct, smooth_viewtx);
+ ARegion *ar = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
+ float w = BLI_rctf_size_x(&ar->v2d.cur);
+ rctf newrct;
+ int nextfra, prevfra;
+
+ switch (U.view_frame_type) {
+ case ZOOM_FRAME_MODE_SECONDS: {
+ const float fps = FPS;
+ newrct.xmax = scene->r.cfra + U.view_frame_seconds * fps + 1;
+ newrct.xmin = scene->r.cfra - U.view_frame_seconds * fps - 1;
+ newrct.ymax = ar->v2d.cur.ymax;
+ newrct.ymin = ar->v2d.cur.ymin;
+ break;
+ }
+
+ /* hardest case of all, look for all keyframes around frame and display those */
+ case ZOOM_FRAME_MODE_KEYFRAMES:
+ if (find_prev_next_keyframes(C, &nextfra, &prevfra)) {
+ newrct.xmax = nextfra;
+ newrct.xmin = prevfra;
+ newrct.ymax = ar->v2d.cur.ymax;
+ newrct.ymin = ar->v2d.cur.ymin;
+ break;
+ }
+ /* else drop through, keep range instead */
+ ATTR_FALLTHROUGH;
+
+ case ZOOM_FRAME_MODE_KEEP_RANGE:
+ default:
+ newrct.xmax = scene->r.cfra + (w / 2);
+ newrct.xmin = scene->r.cfra - (w / 2);
+ newrct.ymax = ar->v2d.cur.ymax;
+ newrct.ymin = ar->v2d.cur.ymin;
+ break;
+ }
+
+ UI_view2d_smooth_view(C, ar, &newrct, smooth_viewtx);
}
/* *************************************************** */
diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c
index dad0727a82d..57ea5ad81f5 100644
--- a/source/blender/editors/animation/anim_filter.c
+++ b/source/blender/editors/animation/anim_filter.c
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
/* This file contains a system used to provide a layer of abstraction between sources
* of animation data and tools in Animation Editors. The method used here involves
* generating a list of edit structures which enable tools to naively perform the actions
@@ -96,7 +95,7 @@
#include "ED_anim_api.h"
#include "ED_markers.h"
-#include "UI_resources.h" /* for TH_KEYFRAME_SCALE lookup */
+#include "UI_resources.h" /* for TH_KEYFRAME_SCALE lookup */
/* ************************************************************ */
/* Blender Context <-> Animation Context mapping */
@@ -106,18 +105,18 @@
/* Get vertical scaling factor (i.e. typically used for keyframe size) */
static void animedit_get_yscale_factor(bAnimContext *ac)
{
- bTheme *btheme = UI_GetTheme();
-
- /* grab scale factor directly from action editor setting
- * NOTE: This theme setting doesn't have an ID, as it cannot be accessed normally
- * since it is a float, and the theme settings methods can only handle chars.
- */
- ac->yscale_fac = btheme->space_action.keyframe_scale_fac;
-
- /* clamp to avoid problems with uninitialised values... */
- if (ac->yscale_fac < 0.1f)
- ac->yscale_fac = 1.0f;
- //printf("yscale_fac = %f\n", ac->yscale_fac);
+ bTheme *btheme = UI_GetTheme();
+
+ /* grab scale factor directly from action editor setting
+ * NOTE: This theme setting doesn't have an ID, as it cannot be accessed normally
+ * since it is a float, and the theme settings methods can only handle chars.
+ */
+ ac->yscale_fac = btheme->space_action.keyframe_scale_fac;
+
+ /* clamp to avoid problems with uninitialised values... */
+ if (ac->yscale_fac < 0.1f)
+ ac->yscale_fac = 1.0f;
+ //printf("yscale_fac = %f\n", ac->yscale_fac);
}
/* ----------- Private Stuff - Action Editor ------------- */
@@ -126,144 +125,144 @@ static void animedit_get_yscale_factor(bAnimContext *ac)
/* Note: there's a similar function in key.c (BKE_key_from_object) */
static Key *actedit_get_shapekeys(bAnimContext *ac)
{
- ViewLayer *view_layer = ac->view_layer;
- Object *ob;
- Key *key;
+ ViewLayer *view_layer = ac->view_layer;
+ Object *ob;
+ Key *key;
- ob = OBACT(view_layer);
- if (ob == NULL)
- return NULL;
+ ob = OBACT(view_layer);
+ if (ob == NULL)
+ return NULL;
- /* XXX pinning is not available in 'ShapeKey' mode... */
- //if (saction->pin) return NULL;
+ /* XXX pinning is not available in 'ShapeKey' mode... */
+ //if (saction->pin) return NULL;
- /* shapekey data is stored with geometry data */
- key = BKE_key_from_object(ob);
+ /* shapekey data is stored with geometry data */
+ key = BKE_key_from_object(ob);
- if (key) {
- if (key->type == KEY_RELATIVE)
- return key;
- }
+ if (key) {
+ if (key->type == KEY_RELATIVE)
+ return key;
+ }
- return NULL;
+ return NULL;
}
/* Get data being edited in Action Editor (depending on current 'mode') */
static bool actedit_get_context(bAnimContext *ac, SpaceAction *saction)
{
- /* get dopesheet */
- ac->ads = &saction->ads;
-
- /* sync settings with current view status, then return appropriate data */
- switch (saction->mode) {
- case SACTCONT_ACTION: /* 'Action Editor' */
- /* if not pinned, sync with active object */
- if (/*saction->pin == 0*/ true) {
- if (ac->obact && ac->obact->adt)
- saction->action = ac->obact->adt->action;
- else
- saction->action = NULL;
- }
-
- ac->datatype = ANIMCONT_ACTION;
- ac->data = saction->action;
-
- ac->mode = saction->mode;
- return true;
-
- case SACTCONT_SHAPEKEY: /* 'ShapeKey Editor' */
- ac->datatype = ANIMCONT_SHAPEKEY;
- ac->data = actedit_get_shapekeys(ac);
-
- /* if not pinned, sync with active object */
- if (/*saction->pin == 0*/ true) {
- Key *key = (Key *)ac->data;
-
- if (key && key->adt)
- saction->action = key->adt->action;
- else
- saction->action = NULL;
- }
-
- ac->mode = saction->mode;
- return true;
-
- case SACTCONT_GPENCIL: /* Grease Pencil */ /* XXX review how this mode is handled... */
- /* update scene-pointer (no need to check for pinning yet, as not implemented) */
- saction->ads.source = (ID *)ac->scene;
-
- ac->datatype = ANIMCONT_GPENCIL;
- ac->data = &saction->ads;
-
- ac->mode = saction->mode;
- return true;
-
- case SACTCONT_CACHEFILE: /* Cache File */ /* XXX review how this mode is handled... */
- /* update scene-pointer (no need to check for pinning yet, as not implemented) */
- saction->ads.source = (ID *)ac->scene;
-
- ac->datatype = ANIMCONT_CHANNEL;
- ac->data = &saction->ads;
-
- ac->mode = saction->mode;
- return true;
-
- case SACTCONT_MASK: /* Mask */ /* XXX review how this mode is handled... */
- {
- /* TODO, other methods to get the mask */
- // Sequence *seq = BKE_sequencer_active_get(ac->scene);
- //MovieClip *clip = ac->scene->clip;
-// struct Mask *mask = seq ? seq->mask : NULL;
-
- /* update scene-pointer (no need to check for pinning yet, as not implemented) */
- saction->ads.source = (ID *)ac->scene;
-
- ac->datatype = ANIMCONT_MASK;
- ac->data = &saction->ads;
-
- ac->mode = saction->mode;
- return true;
- }
-
- case SACTCONT_DOPESHEET: /* DopeSheet */
- /* update scene-pointer (no need to check for pinning yet, as not implemented) */
- saction->ads.source = (ID *)ac->scene;
-
- ac->datatype = ANIMCONT_DOPESHEET;
- ac->data = &saction->ads;
-
- ac->mode = saction->mode;
- return true;
-
- case SACTCONT_TIMELINE: /* Timeline */
- /* update scene-pointer (no need to check for pinning yet, as not implemented) */
- saction->ads.source = (ID *)ac->scene;
-
- /* sync scene's "selected keys only" flag with our "only selected" flag
- * XXX: This is a workaround for T55525. We shouldn't really be syncing the flags like this,
- * but it's a simpler fix for now than also figuring out how the next/prev keyframe tools
- * should work in the 3D View if we allowed full access to the timeline's dopesheet filters
- * (i.e. we'd have to figure out where to host those settings, to be on a scene level like
- * this flag currently is, along with several other unknowns)
- */
- if (ac->scene->flag & SCE_KEYS_NO_SELONLY)
- saction->ads.filterflag &= ~ADS_FILTER_ONLYSEL;
- else
- saction->ads.filterflag |= ADS_FILTER_ONLYSEL;
-
- ac->datatype = ANIMCONT_TIMELINE;
- ac->data = &saction->ads;
-
- ac->mode = saction->mode;
- return true;
-
- default: /* unhandled yet */
- ac->datatype = ANIMCONT_NONE;
- ac->data = NULL;
-
- ac->mode = -1;
- return false;
- }
+ /* get dopesheet */
+ ac->ads = &saction->ads;
+
+ /* sync settings with current view status, then return appropriate data */
+ switch (saction->mode) {
+ case SACTCONT_ACTION: /* 'Action Editor' */
+ /* if not pinned, sync with active object */
+ if (/*saction->pin == 0*/ true) {
+ if (ac->obact && ac->obact->adt)
+ saction->action = ac->obact->adt->action;
+ else
+ saction->action = NULL;
+ }
+
+ ac->datatype = ANIMCONT_ACTION;
+ ac->data = saction->action;
+
+ ac->mode = saction->mode;
+ return true;
+
+ case SACTCONT_SHAPEKEY: /* 'ShapeKey Editor' */
+ ac->datatype = ANIMCONT_SHAPEKEY;
+ ac->data = actedit_get_shapekeys(ac);
+
+ /* if not pinned, sync with active object */
+ if (/*saction->pin == 0*/ true) {
+ Key *key = (Key *)ac->data;
+
+ if (key && key->adt)
+ saction->action = key->adt->action;
+ else
+ saction->action = NULL;
+ }
+
+ ac->mode = saction->mode;
+ return true;
+
+ case SACTCONT_GPENCIL: /* Grease Pencil */ /* XXX review how this mode is handled... */
+ /* update scene-pointer (no need to check for pinning yet, as not implemented) */
+ saction->ads.source = (ID *)ac->scene;
+
+ ac->datatype = ANIMCONT_GPENCIL;
+ ac->data = &saction->ads;
+
+ ac->mode = saction->mode;
+ return true;
+
+ case SACTCONT_CACHEFILE: /* Cache File */ /* XXX review how this mode is handled... */
+ /* update scene-pointer (no need to check for pinning yet, as not implemented) */
+ saction->ads.source = (ID *)ac->scene;
+
+ ac->datatype = ANIMCONT_CHANNEL;
+ ac->data = &saction->ads;
+
+ ac->mode = saction->mode;
+ return true;
+
+ case SACTCONT_MASK: /* Mask */ /* XXX review how this mode is handled... */
+ {
+ /* TODO, other methods to get the mask */
+ // Sequence *seq = BKE_sequencer_active_get(ac->scene);
+ //MovieClip *clip = ac->scene->clip;
+ // struct Mask *mask = seq ? seq->mask : NULL;
+
+ /* update scene-pointer (no need to check for pinning yet, as not implemented) */
+ saction->ads.source = (ID *)ac->scene;
+
+ ac->datatype = ANIMCONT_MASK;
+ ac->data = &saction->ads;
+
+ ac->mode = saction->mode;
+ return true;
+ }
+
+ case SACTCONT_DOPESHEET: /* DopeSheet */
+ /* update scene-pointer (no need to check for pinning yet, as not implemented) */
+ saction->ads.source = (ID *)ac->scene;
+
+ ac->datatype = ANIMCONT_DOPESHEET;
+ ac->data = &saction->ads;
+
+ ac->mode = saction->mode;
+ return true;
+
+ case SACTCONT_TIMELINE: /* Timeline */
+ /* update scene-pointer (no need to check for pinning yet, as not implemented) */
+ saction->ads.source = (ID *)ac->scene;
+
+ /* sync scene's "selected keys only" flag with our "only selected" flag
+ * XXX: This is a workaround for T55525. We shouldn't really be syncing the flags like this,
+ * but it's a simpler fix for now than also figuring out how the next/prev keyframe tools
+ * should work in the 3D View if we allowed full access to the timeline's dopesheet filters
+ * (i.e. we'd have to figure out where to host those settings, to be on a scene level like
+ * this flag currently is, along with several other unknowns)
+ */
+ if (ac->scene->flag & SCE_KEYS_NO_SELONLY)
+ saction->ads.filterflag &= ~ADS_FILTER_ONLYSEL;
+ else
+ saction->ads.filterflag |= ADS_FILTER_ONLYSEL;
+
+ ac->datatype = ANIMCONT_TIMELINE;
+ ac->data = &saction->ads;
+
+ ac->mode = saction->mode;
+ return true;
+
+ default: /* unhandled yet */
+ ac->datatype = ANIMCONT_NONE;
+ ac->data = NULL;
+
+ ac->mode = -1;
+ return false;
+ }
}
/* ----------- Private Stuff - Graph Editor ------------- */
@@ -271,50 +270,50 @@ static bool actedit_get_context(bAnimContext *ac, SpaceAction *saction)
/* Get data being edited in Graph Editor (depending on current 'mode') */
static bool graphedit_get_context(bAnimContext *ac, SpaceGraph *sipo)
{
- /* init dopesheet data if non-existent (i.e. for old files) */
- if (sipo->ads == NULL) {
- sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
- sipo->ads->source = (ID *)ac->scene;
- }
- ac->ads = sipo->ads;
-
- /* set settings for Graph Editor - "Selected = Editable" */
- if (sipo->flag & SIPO_SELCUVERTSONLY)
- sipo->ads->filterflag |= ADS_FILTER_SELEDIT;
- else
- sipo->ads->filterflag &= ~ADS_FILTER_SELEDIT;
-
- /* sync settings with current view status, then return appropriate data */
- switch (sipo->mode) {
- case SIPO_MODE_ANIMATION: /* Animation F-Curve Editor */
- /* update scene-pointer (no need to check for pinning yet, as not implemented) */
- sipo->ads->source = (ID *)ac->scene;
- sipo->ads->filterflag &= ~ADS_FILTER_ONLYDRIVERS;
-
- ac->datatype = ANIMCONT_FCURVES;
- ac->data = sipo->ads;
-
- ac->mode = sipo->mode;
- return true;
-
- case SIPO_MODE_DRIVERS: /* Driver F-Curve Editor */
- /* update scene-pointer (no need to check for pinning yet, as not implemented) */
- sipo->ads->source = (ID *)ac->scene;
- sipo->ads->filterflag |= ADS_FILTER_ONLYDRIVERS;
-
- ac->datatype = ANIMCONT_DRIVERS;
- ac->data = sipo->ads;
-
- ac->mode = sipo->mode;
- return true;
-
- default: /* unhandled yet */
- ac->datatype = ANIMCONT_NONE;
- ac->data = NULL;
-
- ac->mode = -1;
- return false;
- }
+ /* init dopesheet data if non-existent (i.e. for old files) */
+ if (sipo->ads == NULL) {
+ sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
+ sipo->ads->source = (ID *)ac->scene;
+ }
+ ac->ads = sipo->ads;
+
+ /* set settings for Graph Editor - "Selected = Editable" */
+ if (sipo->flag & SIPO_SELCUVERTSONLY)
+ sipo->ads->filterflag |= ADS_FILTER_SELEDIT;
+ else
+ sipo->ads->filterflag &= ~ADS_FILTER_SELEDIT;
+
+ /* sync settings with current view status, then return appropriate data */
+ switch (sipo->mode) {
+ case SIPO_MODE_ANIMATION: /* Animation F-Curve Editor */
+ /* update scene-pointer (no need to check for pinning yet, as not implemented) */
+ sipo->ads->source = (ID *)ac->scene;
+ sipo->ads->filterflag &= ~ADS_FILTER_ONLYDRIVERS;
+
+ ac->datatype = ANIMCONT_FCURVES;
+ ac->data = sipo->ads;
+
+ ac->mode = sipo->mode;
+ return true;
+
+ case SIPO_MODE_DRIVERS: /* Driver F-Curve Editor */
+ /* update scene-pointer (no need to check for pinning yet, as not implemented) */
+ sipo->ads->source = (ID *)ac->scene;
+ sipo->ads->filterflag |= ADS_FILTER_ONLYDRIVERS;
+
+ ac->datatype = ANIMCONT_DRIVERS;
+ ac->data = sipo->ads;
+
+ ac->mode = sipo->mode;
+ return true;
+
+ default: /* unhandled yet */
+ ac->datatype = ANIMCONT_NONE;
+ ac->data = NULL;
+
+ ac->mode = -1;
+ return false;
+ }
}
/* ----------- Private Stuff - NLA Editor ------------- */
@@ -322,20 +321,20 @@ static bool graphedit_get_context(bAnimContext *ac, SpaceGraph *sipo)
/* Get data being edited in Graph Editor (depending on current 'mode') */
static bool nlaedit_get_context(bAnimContext *ac, SpaceNla *snla)
{
- /* init dopesheet data if non-existent (i.e. for old files) */
- if (snla->ads == NULL)
- snla->ads = MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet");
- ac->ads = snla->ads;
+ /* init dopesheet data if non-existent (i.e. for old files) */
+ if (snla->ads == NULL)
+ snla->ads = MEM_callocN(sizeof(bDopeSheet), "NlaEdit DopeSheet");
+ ac->ads = snla->ads;
- /* sync settings with current view status, then return appropriate data */
- /* update scene-pointer (no need to check for pinning yet, as not implemented) */
- snla->ads->source = (ID *)ac->scene;
- snla->ads->filterflag |= ADS_FILTER_ONLYNLA;
+ /* sync settings with current view status, then return appropriate data */
+ /* update scene-pointer (no need to check for pinning yet, as not implemented) */
+ snla->ads->source = (ID *)ac->scene;
+ snla->ads->filterflag |= ADS_FILTER_ONLYNLA;
- ac->datatype = ANIMCONT_NLA;
- ac->data = snla->ads;
+ ac->datatype = ANIMCONT_NLA;
+ ac->data = snla->ads;
- return true;
+ return true;
}
/* ----------- Public API --------------- */
@@ -346,35 +345,32 @@ static bool nlaedit_get_context(bAnimContext *ac, SpaceNla *snla)
*/
bool ANIM_animdata_context_getdata(bAnimContext *ac)
{
- SpaceLink *sl = ac->sl;
- bool ok = false;
-
- /* context depends on editor we are currently in */
- if (sl) {
- switch (ac->spacetype) {
- case SPACE_ACTION:
- {
- SpaceAction *saction = (SpaceAction *)sl;
- ok = actedit_get_context(ac, saction);
- break;
- }
- case SPACE_GRAPH:
- {
- SpaceGraph *sipo = (SpaceGraph *)sl;
- ok = graphedit_get_context(ac, sipo);
- break;
- }
- case SPACE_NLA:
- {
- SpaceNla *snla = (SpaceNla *)sl;
- ok = nlaedit_get_context(ac, snla);
- break;
- }
- }
- }
-
- /* check if there's any valid data */
- return (ok && ac->data);
+ SpaceLink *sl = ac->sl;
+ bool ok = false;
+
+ /* context depends on editor we are currently in */
+ if (sl) {
+ switch (ac->spacetype) {
+ case SPACE_ACTION: {
+ SpaceAction *saction = (SpaceAction *)sl;
+ ok = actedit_get_context(ac, saction);
+ break;
+ }
+ case SPACE_GRAPH: {
+ SpaceGraph *sipo = (SpaceGraph *)sl;
+ ok = graphedit_get_context(ac, sipo);
+ break;
+ }
+ case SPACE_NLA: {
+ SpaceNla *snla = (SpaceNla *)sl;
+ ok = nlaedit_get_context(ac, snla);
+ break;
+ }
+ }
+ }
+
+ /* check if there's any valid data */
+ return (ok && ac->data);
}
/* Obtain current anim-data context from Blender Context info
@@ -384,37 +380,38 @@ bool ANIM_animdata_context_getdata(bAnimContext *ac)
*/
bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
{
- Main *bmain = CTX_data_main(C);
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = CTX_wm_region(C);
- SpaceLink *sl = CTX_wm_space_data(C);
- Scene *scene = CTX_data_scene(C);
-
- /* clear old context info */
- if (ac == NULL) return false;
- memset(ac, 0, sizeof(bAnimContext));
-
- /* get useful default context settings from context */
- ac->bmain = bmain;
- ac->scene = scene;
- if (scene) {
- ac->markers = ED_context_get_markers(C);
- }
- ac->depsgraph = CTX_data_depsgraph(C);
- ac->view_layer = CTX_data_view_layer(C);
- ac->obact = (ac->view_layer->basact) ? ac->view_layer->basact->object : NULL;
- ac->sa = sa;
- ac->ar = ar;
- ac->sl = sl;
- ac->spacetype = (sa) ? sa->spacetype : 0;
- ac->regiontype = (ar) ? ar->regiontype : 0;
-
- /* initialise default y-scale factor */
- animedit_get_yscale_factor(ac);
-
- /* get data context info */
- // XXX: if the below fails, try to grab this info from context instead... (to allow for scripting)
- return ANIM_animdata_context_getdata(ac);
+ Main *bmain = CTX_data_main(C);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = CTX_wm_region(C);
+ SpaceLink *sl = CTX_wm_space_data(C);
+ Scene *scene = CTX_data_scene(C);
+
+ /* clear old context info */
+ if (ac == NULL)
+ return false;
+ memset(ac, 0, sizeof(bAnimContext));
+
+ /* get useful default context settings from context */
+ ac->bmain = bmain;
+ ac->scene = scene;
+ if (scene) {
+ ac->markers = ED_context_get_markers(C);
+ }
+ ac->depsgraph = CTX_data_depsgraph(C);
+ ac->view_layer = CTX_data_view_layer(C);
+ ac->obact = (ac->view_layer->basact) ? ac->view_layer->basact->object : NULL;
+ ac->sa = sa;
+ ac->ar = ar;
+ ac->sl = sl;
+ ac->spacetype = (sa) ? sa->spacetype : 0;
+ ac->regiontype = (ar) ? ar->regiontype : 0;
+
+ /* initialise default y-scale factor */
+ animedit_get_yscale_factor(ac);
+
+ /* get data context info */
+ // XXX: if the below fails, try to grab this info from context instead... (to allow for scripting)
+ return ANIM_animdata_context_getdata(ac);
}
/* ************************************************************ */
@@ -439,24 +436,25 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
* one case below.
*/
#define BEGIN_ANIMFILTER_SUBCHANNELS(expanded_check) \
- { \
- int _filter = filter_mode; \
- short _doSubChannels = 0; \
- if (!(filter_mode & ANIMFILTER_LIST_VISIBLE) || (expanded_check)) \
- _doSubChannels = 1; \
- else if (!(filter_mode & ANIMFILTER_LIST_CHANNELS)) \
- _doSubChannels = 2; \
- else { \
- filter_mode |= ANIMFILTER_TMP_PEEK; \
- } \
- \
- { \
- (void) _doSubChannels; \
- }
+ { \
+ int _filter = filter_mode; \
+ short _doSubChannels = 0; \
+ if (!(filter_mode & ANIMFILTER_LIST_VISIBLE) || (expanded_check)) \
+ _doSubChannels = 1; \
+ else if (!(filter_mode & ANIMFILTER_LIST_CHANNELS)) \
+ _doSubChannels = 2; \
+ else { \
+ filter_mode |= ANIMFILTER_TMP_PEEK; \
+ } \
+\
+ { \
+ (void)_doSubChannels; \
+ }
/* ... standard sub-channel filtering can go on here now ... */
#define END_ANIMFILTER_SUBCHANNELS \
- filter_mode = _filter; \
- } (void)0
+ filter_mode = _filter; \
+ } \
+ (void)0
/* ............................... */
@@ -500,36 +498,38 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
* 4B) normal keyframes: only when there is an active action
*/
#define ANIMDATA_FILTER_CASES(id, adtOk, nlaOk, driversOk, nlaKeysOk, keysOk) \
- { \
- if ((id)->adt) { \
- if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || !((id)->adt->flag & ADT_CURVES_NOT_VISIBLE)) { \
- if (filter_mode & ANIMFILTER_ANIMDATA) { \
- adtOk \
- } \
- else if (ads->filterflag & ADS_FILTER_ONLYNLA) { \
- if (ANIMDATA_HAS_NLA(id)) { \
- nlaOk \
- } \
- else if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) || ANIMDATA_HAS_KEYS(id)) { \
- nlaOk \
- } \
- } \
- else if (ads->filterflag & ADS_FILTER_ONLYDRIVERS) { \
- if (ANIMDATA_HAS_DRIVERS(id)) { \
- driversOk \
- } \
- } \
- else { \
- if (ANIMDATA_HAS_NLA(id)) { \
- nlaKeysOk \
- } \
- if (ANIMDATA_HAS_KEYS(id)) { \
- keysOk \
- } \
- } \
- } \
- } \
- } (void)0
+ { \
+ if ((id)->adt) { \
+ if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || \
+ !((id)->adt->flag & ADT_CURVES_NOT_VISIBLE)) { \
+ if (filter_mode & ANIMFILTER_ANIMDATA) { \
+ adtOk \
+ } \
+ else if (ads->filterflag & ADS_FILTER_ONLYNLA) { \
+ if (ANIMDATA_HAS_NLA(id)) { \
+ nlaOk \
+ } \
+ else if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) || ANIMDATA_HAS_KEYS(id)) { \
+ nlaOk \
+ } \
+ } \
+ else if (ads->filterflag & ADS_FILTER_ONLYDRIVERS) { \
+ if (ANIMDATA_HAS_DRIVERS(id)) { \
+ driversOk \
+ } \
+ } \
+ else { \
+ if (ANIMDATA_HAS_NLA(id)) { \
+ nlaKeysOk \
+ } \
+ if (ANIMDATA_HAS_KEYS(id)) { \
+ keysOk \
+ } \
+ } \
+ } \
+ } \
+ } \
+ (void)0
/* ............................... */
@@ -539,32 +539,35 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
* ! This causes the calling function to return early if we're only "peeking" for channels
*/
// XXX: ale_statement stuff is really a hack for one special case. It shouldn't really be needed...
-#define ANIMCHANNEL_NEW_CHANNEL_FULL(channel_data, channel_type, owner_id, fcurve_owner_id, ale_statement) \
- if (filter_mode & ANIMFILTER_TMP_PEEK) \
- return 1; \
- else { \
- bAnimListElem *ale = make_new_animlistelem(channel_data, channel_type, (ID *)owner_id, fcurve_owner_id); \
- if (ale) { \
- BLI_addtail(anim_data, ale); \
- items ++; \
- ale_statement \
- } \
- } (void)0
+#define ANIMCHANNEL_NEW_CHANNEL_FULL( \
+ channel_data, channel_type, owner_id, fcurve_owner_id, ale_statement) \
+ if (filter_mode & ANIMFILTER_TMP_PEEK) \
+ return 1; \
+ else { \
+ bAnimListElem *ale = make_new_animlistelem( \
+ channel_data, channel_type, (ID *)owner_id, fcurve_owner_id); \
+ if (ale) { \
+ BLI_addtail(anim_data, ale); \
+ items++; \
+ ale_statement \
+ } \
+ } \
+ (void)0
#define ANIMCHANNEL_NEW_CHANNEL(channel_data, channel_type, owner_id, fcurve_owner_id) \
- ANIMCHANNEL_NEW_CHANNEL_FULL(channel_data, channel_type, owner_id, fcurve_owner_id, {})
+ ANIMCHANNEL_NEW_CHANNEL_FULL(channel_data, channel_type, owner_id, fcurve_owner_id, {})
/* ............................... */
/* quick macro to test if an anim-channel representing an AnimData block is suitably active */
#define ANIMCHANNEL_ACTIVEOK(ale) \
- (!(filter_mode & ANIMFILTER_ACTIVE) || !(ale->adt) || (ale->adt->flag & ADT_UI_ACTIVE) )
+ (!(filter_mode & ANIMFILTER_ACTIVE) || !(ale->adt) || (ale->adt->flag & ADT_UI_ACTIVE))
/* quick macro to test if an anim-channel (F-Curve, Group, etc.) is selected in an acceptable way */
#define ANIMCHANNEL_SELOK(test_func) \
- (!(filter_mode & (ANIMFILTER_SEL | ANIMFILTER_UNSEL)) || \
- ((filter_mode & ANIMFILTER_SEL) && test_func) || \
- ((filter_mode & ANIMFILTER_UNSEL) && test_func == 0) )
+ (!(filter_mode & (ANIMFILTER_SEL | ANIMFILTER_UNSEL)) || \
+ ((filter_mode & ANIMFILTER_SEL) && test_func) || \
+ ((filter_mode & ANIMFILTER_UNSEL) && test_func == 0))
/* quick macro to test if an anim-channel (F-Curve) is selected ok for editing purposes
* - _SELEDIT means that only selected curves will have visible+editable keyframes
@@ -575,414 +578,386 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac)
* 3) test_func (i.e. selection test) - only if selected, this test will pass
*/
#define ANIMCHANNEL_SELEDITOK(test_func) \
- (!(filter_mode & ANIMFILTER_SELEDIT) || \
- !(filter_mode & ANIMFILTER_FOREDIT) || \
- (test_func) )
+ (!(filter_mode & ANIMFILTER_SELEDIT) || !(filter_mode & ANIMFILTER_FOREDIT) || (test_func))
/* ----------- 'Private' Stuff --------------- */
/* this function allocates memory for a new bAnimListElem struct for the
* provided animation channel-data.
*/
-static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owner_id, ID *fcurve_owner_id)
+static bAnimListElem *make_new_animlistelem(void *data,
+ short datatype,
+ ID *owner_id,
+ ID *fcurve_owner_id)
{
- bAnimListElem *ale = NULL;
-
- /* only allocate memory if there is data to convert */
- if (data) {
- /* allocate and set generic data */
- ale = MEM_callocN(sizeof(bAnimListElem), "bAnimListElem");
-
- ale->data = data;
- ale->type = datatype;
-
- ale->id = owner_id;
- ale->adt = BKE_animdata_from_id(owner_id);
- ale->fcurve_owner_id = fcurve_owner_id;
-
- /* do specifics */
- switch (datatype) {
- case ANIMTYPE_SUMMARY:
- {
- /* nothing to include for now... this is just a dummy wrappy around all the other channels
- * in the DopeSheet, and gets included at the start of the list
- */
- ale->key_data = NULL;
- ale->datatype = ALE_ALL;
- break;
- }
- case ANIMTYPE_SCENE:
- {
- Scene *sce = (Scene *)data;
-
- ale->flag = sce->flag;
-
- ale->key_data = sce;
- ale->datatype = ALE_SCE;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_OBJECT:
- {
- Base *base = (Base *)data;
- Object *ob = base->object;
-
- ale->flag = ob->flag;
-
- ale->key_data = ob;
- ale->datatype = ALE_OB;
-
- ale->adt = BKE_animdata_from_id(&ob->id);
- break;
- }
- case ANIMTYPE_FILLACTD:
- {
- bAction *act = (bAction *)data;
-
- ale->flag = act->flag;
-
- ale->key_data = act;
- ale->datatype = ALE_ACT;
- break;
- }
- case ANIMTYPE_FILLDRIVERS:
- {
- AnimData *adt = (AnimData *)data;
-
- ale->flag = adt->flag;
-
- // XXX... drivers don't show summary for now
- ale->key_data = NULL;
- ale->datatype = ALE_NONE;
- break;
- }
- case ANIMTYPE_DSMAT:
- {
- Material *ma = (Material *)data;
- AnimData *adt = ma->adt;
-
- ale->flag = FILTER_MAT_OBJD(ma);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSLAM:
- {
- Light *la = (Light *)data;
- AnimData *adt = la->adt;
-
- ale->flag = FILTER_LAM_OBJD(la);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSCAM:
- {
- Camera *ca = (Camera *)data;
- AnimData *adt = ca->adt;
-
- ale->flag = FILTER_CAM_OBJD(ca);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSCACHEFILE:
- {
- CacheFile *cache_file = (CacheFile *)data;
- AnimData *adt = cache_file->adt;
-
- ale->flag = FILTER_CACHEFILE_OBJD(cache_file);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSCUR:
- {
- Curve *cu = (Curve *)data;
- AnimData *adt = cu->adt;
-
- ale->flag = FILTER_CUR_OBJD(cu);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSARM:
- {
- bArmature *arm = (bArmature *)data;
- AnimData *adt = arm->adt;
-
- ale->flag = FILTER_ARM_OBJD(arm);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSMESH:
- {
- Mesh *me = (Mesh *)data;
- AnimData *adt = me->adt;
-
- ale->flag = FILTER_MESH_OBJD(me);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSLAT:
- {
- Lattice *lt = (Lattice *)data;
- AnimData *adt = lt->adt;
-
- ale->flag = FILTER_LATTICE_OBJD(lt);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSSPK:
- {
- Speaker *spk = (Speaker *)data;
- AnimData *adt = spk->adt;
-
- ale->flag = FILTER_SPK_OBJD(spk);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSSKEY:
- {
- Key *key = (Key *)data;
- AnimData *adt = key->adt;
-
- ale->flag = FILTER_SKE_OBJD(key);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSWOR:
- {
- World *wo = (World *)data;
- AnimData *adt = wo->adt;
-
- ale->flag = FILTER_WOR_SCED(wo);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSNTREE:
- {
- bNodeTree *ntree = (bNodeTree *)data;
- AnimData *adt = ntree->adt;
-
- ale->flag = FILTER_NTREE_DATA(ntree);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSLINESTYLE:
- {
- FreestyleLineStyle *linestyle = (FreestyleLineStyle *)data;
- AnimData *adt = linestyle->adt;
-
- ale->flag = FILTER_LS_SCED(linestyle);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSPART:
- {
- ParticleSettings *part = (ParticleSettings *)ale->data;
- AnimData *adt = part->adt;
-
- ale->flag = FILTER_PART_OBJD(part);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSTEX:
- {
- Tex *tex = (Tex *)data;
- AnimData *adt = tex->adt;
-
- ale->flag = FILTER_TEX_DATA(tex);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSGPENCIL:
- {
- bGPdata *gpd = (bGPdata *)data;
- AnimData *adt = gpd->adt;
-
- /* NOTE: we just reuse the same expand filter for this case */
- ale->flag = EXPANDED_GPD(gpd);
-
- // XXX: currently, this is only used for access to its animation data
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_DSMCLIP:
- {
- MovieClip *clip = (MovieClip *)data;
- AnimData *adt = clip->adt;
-
- ale->flag = EXPANDED_MCLIP(clip);
-
- ale->key_data = (adt) ? adt->action : NULL;
- ale->datatype = ALE_ACT;
-
- ale->adt = BKE_animdata_from_id(data);
- break;
- }
- case ANIMTYPE_NLACONTROLS:
- {
- AnimData *adt = (AnimData *)data;
-
- ale->flag = adt->flag;
-
- ale->key_data = NULL;
- ale->datatype = ALE_NONE;
- break;
- }
- case ANIMTYPE_GROUP:
- {
- bActionGroup *agrp = (bActionGroup *)data;
-
- ale->flag = agrp->flag;
-
- ale->key_data = NULL;
- ale->datatype = ALE_GROUP;
- break;
- }
- case ANIMTYPE_FCURVE:
- case ANIMTYPE_NLACURVE: /* practically the same as ANIMTYPE_FCURVE.
- * Differences are applied post-creation */
- {
- FCurve *fcu = (FCurve *)data;
-
- ale->flag = fcu->flag;
-
- ale->key_data = fcu;
- ale->datatype = ALE_FCURVE;
- break;
- }
- case ANIMTYPE_SHAPEKEY:
- {
- KeyBlock *kb = (KeyBlock *)data;
- Key *key = (Key *)ale->id;
-
- ale->flag = kb->flag;
-
- /* whether we have keyframes depends on whether there is a Key block to find it from */
- if (key) {
- /* index of shapekey is defined by place in key's list */
- ale->index = BLI_findindex(&key->block, kb);
-
- /* the corresponding keyframes are from the animdata */
- if (ale->adt && ale->adt->action) {
- bAction *act = ale->adt->action;
- char *rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
-
- /* try to find the F-Curve which corresponds to this exactly,
- * then free the MEM_alloc'd string
- */
- if (rna_path) {
- ale->key_data = (void *)list_find_fcurve(&act->curves, rna_path, 0);
- MEM_freeN(rna_path);
- }
- }
- ale->datatype = (ale->key_data) ? ALE_FCURVE : ALE_NONE;
- }
- break;
- }
- case ANIMTYPE_GPLAYER:
- {
- bGPDlayer *gpl = (bGPDlayer *)data;
-
- ale->flag = gpl->flag;
-
- ale->key_data = NULL;
- ale->datatype = ALE_GPFRAME;
- break;
- }
- case ANIMTYPE_MASKLAYER:
- {
- MaskLayer *masklay = (MaskLayer *)data;
-
- ale->flag = masklay->flag;
-
- ale->key_data = NULL;
- ale->datatype = ALE_MASKLAY;
- break;
- }
- case ANIMTYPE_NLATRACK:
- {
- NlaTrack *nlt = (NlaTrack *)data;
-
- ale->flag = nlt->flag;
-
- ale->key_data = &nlt->strips;
- ale->datatype = ALE_NLASTRIP;
- break;
- }
- case ANIMTYPE_NLAACTION:
- {
- /* nothing to include for now... nothing editable from NLA-perspective here */
- ale->key_data = NULL;
- ale->datatype = ALE_NONE;
- break;
- }
- }
- }
-
- /* return created datatype */
- return ale;
+ bAnimListElem *ale = NULL;
+
+ /* only allocate memory if there is data to convert */
+ if (data) {
+ /* allocate and set generic data */
+ ale = MEM_callocN(sizeof(bAnimListElem), "bAnimListElem");
+
+ ale->data = data;
+ ale->type = datatype;
+
+ ale->id = owner_id;
+ ale->adt = BKE_animdata_from_id(owner_id);
+ ale->fcurve_owner_id = fcurve_owner_id;
+
+ /* do specifics */
+ switch (datatype) {
+ case ANIMTYPE_SUMMARY: {
+ /* nothing to include for now... this is just a dummy wrappy around all the other channels
+ * in the DopeSheet, and gets included at the start of the list
+ */
+ ale->key_data = NULL;
+ ale->datatype = ALE_ALL;
+ break;
+ }
+ case ANIMTYPE_SCENE: {
+ Scene *sce = (Scene *)data;
+
+ ale->flag = sce->flag;
+
+ ale->key_data = sce;
+ ale->datatype = ALE_SCE;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_OBJECT: {
+ Base *base = (Base *)data;
+ Object *ob = base->object;
+
+ ale->flag = ob->flag;
+
+ ale->key_data = ob;
+ ale->datatype = ALE_OB;
+
+ ale->adt = BKE_animdata_from_id(&ob->id);
+ break;
+ }
+ case ANIMTYPE_FILLACTD: {
+ bAction *act = (bAction *)data;
+
+ ale->flag = act->flag;
+
+ ale->key_data = act;
+ ale->datatype = ALE_ACT;
+ break;
+ }
+ case ANIMTYPE_FILLDRIVERS: {
+ AnimData *adt = (AnimData *)data;
+
+ ale->flag = adt->flag;
+
+ // XXX... drivers don't show summary for now
+ ale->key_data = NULL;
+ ale->datatype = ALE_NONE;
+ break;
+ }
+ case ANIMTYPE_DSMAT: {
+ Material *ma = (Material *)data;
+ AnimData *adt = ma->adt;
+
+ ale->flag = FILTER_MAT_OBJD(ma);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSLAM: {
+ Light *la = (Light *)data;
+ AnimData *adt = la->adt;
+
+ ale->flag = FILTER_LAM_OBJD(la);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSCAM: {
+ Camera *ca = (Camera *)data;
+ AnimData *adt = ca->adt;
+
+ ale->flag = FILTER_CAM_OBJD(ca);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSCACHEFILE: {
+ CacheFile *cache_file = (CacheFile *)data;
+ AnimData *adt = cache_file->adt;
+
+ ale->flag = FILTER_CACHEFILE_OBJD(cache_file);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSCUR: {
+ Curve *cu = (Curve *)data;
+ AnimData *adt = cu->adt;
+
+ ale->flag = FILTER_CUR_OBJD(cu);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSARM: {
+ bArmature *arm = (bArmature *)data;
+ AnimData *adt = arm->adt;
+
+ ale->flag = FILTER_ARM_OBJD(arm);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSMESH: {
+ Mesh *me = (Mesh *)data;
+ AnimData *adt = me->adt;
+
+ ale->flag = FILTER_MESH_OBJD(me);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSLAT: {
+ Lattice *lt = (Lattice *)data;
+ AnimData *adt = lt->adt;
+
+ ale->flag = FILTER_LATTICE_OBJD(lt);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSSPK: {
+ Speaker *spk = (Speaker *)data;
+ AnimData *adt = spk->adt;
+
+ ale->flag = FILTER_SPK_OBJD(spk);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSSKEY: {
+ Key *key = (Key *)data;
+ AnimData *adt = key->adt;
+
+ ale->flag = FILTER_SKE_OBJD(key);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSWOR: {
+ World *wo = (World *)data;
+ AnimData *adt = wo->adt;
+
+ ale->flag = FILTER_WOR_SCED(wo);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSNTREE: {
+ bNodeTree *ntree = (bNodeTree *)data;
+ AnimData *adt = ntree->adt;
+
+ ale->flag = FILTER_NTREE_DATA(ntree);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSLINESTYLE: {
+ FreestyleLineStyle *linestyle = (FreestyleLineStyle *)data;
+ AnimData *adt = linestyle->adt;
+
+ ale->flag = FILTER_LS_SCED(linestyle);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSPART: {
+ ParticleSettings *part = (ParticleSettings *)ale->data;
+ AnimData *adt = part->adt;
+
+ ale->flag = FILTER_PART_OBJD(part);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSTEX: {
+ Tex *tex = (Tex *)data;
+ AnimData *adt = tex->adt;
+
+ ale->flag = FILTER_TEX_DATA(tex);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSGPENCIL: {
+ bGPdata *gpd = (bGPdata *)data;
+ AnimData *adt = gpd->adt;
+
+ /* NOTE: we just reuse the same expand filter for this case */
+ ale->flag = EXPANDED_GPD(gpd);
+
+ // XXX: currently, this is only used for access to its animation data
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_DSMCLIP: {
+ MovieClip *clip = (MovieClip *)data;
+ AnimData *adt = clip->adt;
+
+ ale->flag = EXPANDED_MCLIP(clip);
+
+ ale->key_data = (adt) ? adt->action : NULL;
+ ale->datatype = ALE_ACT;
+
+ ale->adt = BKE_animdata_from_id(data);
+ break;
+ }
+ case ANIMTYPE_NLACONTROLS: {
+ AnimData *adt = (AnimData *)data;
+
+ ale->flag = adt->flag;
+
+ ale->key_data = NULL;
+ ale->datatype = ALE_NONE;
+ break;
+ }
+ case ANIMTYPE_GROUP: {
+ bActionGroup *agrp = (bActionGroup *)data;
+
+ ale->flag = agrp->flag;
+
+ ale->key_data = NULL;
+ ale->datatype = ALE_GROUP;
+ break;
+ }
+ case ANIMTYPE_FCURVE:
+ case ANIMTYPE_NLACURVE: /* practically the same as ANIMTYPE_FCURVE.
+ * Differences are applied post-creation */
+ {
+ FCurve *fcu = (FCurve *)data;
+
+ ale->flag = fcu->flag;
+
+ ale->key_data = fcu;
+ ale->datatype = ALE_FCURVE;
+ break;
+ }
+ case ANIMTYPE_SHAPEKEY: {
+ KeyBlock *kb = (KeyBlock *)data;
+ Key *key = (Key *)ale->id;
+
+ ale->flag = kb->flag;
+
+ /* whether we have keyframes depends on whether there is a Key block to find it from */
+ if (key) {
+ /* index of shapekey is defined by place in key's list */
+ ale->index = BLI_findindex(&key->block, kb);
+
+ /* the corresponding keyframes are from the animdata */
+ if (ale->adt && ale->adt->action) {
+ bAction *act = ale->adt->action;
+ char *rna_path = BKE_keyblock_curval_rnapath_get(key, kb);
+
+ /* try to find the F-Curve which corresponds to this exactly,
+ * then free the MEM_alloc'd string
+ */
+ if (rna_path) {
+ ale->key_data = (void *)list_find_fcurve(&act->curves, rna_path, 0);
+ MEM_freeN(rna_path);
+ }
+ }
+ ale->datatype = (ale->key_data) ? ALE_FCURVE : ALE_NONE;
+ }
+ break;
+ }
+ case ANIMTYPE_GPLAYER: {
+ bGPDlayer *gpl = (bGPDlayer *)data;
+
+ ale->flag = gpl->flag;
+
+ ale->key_data = NULL;
+ ale->datatype = ALE_GPFRAME;
+ break;
+ }
+ case ANIMTYPE_MASKLAYER: {
+ MaskLayer *masklay = (MaskLayer *)data;
+
+ ale->flag = masklay->flag;
+
+ ale->key_data = NULL;
+ ale->datatype = ALE_MASKLAY;
+ break;
+ }
+ case ANIMTYPE_NLATRACK: {
+ NlaTrack *nlt = (NlaTrack *)data;
+
+ ale->flag = nlt->flag;
+
+ ale->key_data = &nlt->strips;
+ ale->datatype = ALE_NLASTRIP;
+ break;
+ }
+ case ANIMTYPE_NLAACTION: {
+ /* nothing to include for now... nothing editable from NLA-perspective here */
+ ale->key_data = NULL;
+ ale->datatype = ALE_NONE;
+ break;
+ }
+ }
+ }
+
+ /* return created datatype */
+ return ale;
}
/* ----------------------------------------- */
@@ -992,154 +967,160 @@ static bAnimListElem *make_new_animlistelem(void *data, short datatype, ID *owne
*/
static bool skip_fcurve_selected_data(bDopeSheet *ads, FCurve *fcu, ID *owner_id, int filter_mode)
{
- if (fcu->grp != NULL && fcu->grp->flag & ADT_CURVES_ALWAYS_VISIBLE) {
- return false;
- }
- /* hidden items should be skipped if we only care about visible data,
- * but we aren't interested in hidden stuff */
- const bool skip_hidden = (filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN);
-
- if (GS(owner_id->name) == ID_OB) {
- Object *ob = (Object *)owner_id;
-
- /* only consider if F-Curve involves pose.bones */
- if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones")) {
- bPoseChannel *pchan;
- char *bone_name;
-
- /* get bone-name, and check if this bone is selected */
- bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
- pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
- if (bone_name) MEM_freeN(bone_name);
-
- /* check whether to continue or skip */
- if ((pchan) && (pchan->bone)) {
- /* if only visible channels, skip if bone not visible unless user wants channels from hidden data too */
- if (skip_hidden) {
- bArmature *arm = (bArmature *)ob->data;
-
- /* skipping - not visible on currently visible layers */
- if ((arm->layer & pchan->bone->layer) == 0)
- return true;
- /* skipping - is currently hidden */
- if (pchan->bone->flag & BONE_HIDDEN_P)
- return true;
- }
-
- /* can only add this F-Curve if it is selected */
- if (ads->filterflag & ADS_FILTER_ONLYSEL) {
- if ((pchan->bone->flag & BONE_SELECTED) == 0)
- return true;
- }
- }
- }
- }
- else if (GS(owner_id->name) == ID_SCE) {
- Scene *scene = (Scene *)owner_id;
-
- /* only consider if F-Curve involves sequence_editor.sequences */
- if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
- Editing *ed = BKE_sequencer_editing_get(scene, false);
- Sequence *seq = NULL;
- char *seq_name;
-
- if (ed) {
- /* get strip name, and check if this strip is selected */
- seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
- seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false);
- if (seq_name) MEM_freeN(seq_name);
- }
-
- /* can only add this F-Curve if it is selected */
- if (ads->filterflag & ADS_FILTER_ONLYSEL) {
- if ((seq == NULL) || (seq->flag & SELECT) == 0)
- return true;
- }
- }
- }
- else if (GS(owner_id->name) == ID_NT) {
- bNodeTree *ntree = (bNodeTree *)owner_id;
-
- /* check for selected nodes */
- if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) {
- bNode *node;
- char *node_name;
-
- /* get strip name, and check if this strip is selected */
- node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes[");
- node = nodeFindNodebyName(ntree, node_name);
- if (node_name) MEM_freeN(node_name);
-
- /* can only add this F-Curve if it is selected */
- if (ads->filterflag & ADS_FILTER_ONLYSEL) {
- if ((node) && (node->flag & NODE_SELECT) == 0)
- return true;
- }
- }
- }
-
- return false;
+ if (fcu->grp != NULL && fcu->grp->flag & ADT_CURVES_ALWAYS_VISIBLE) {
+ return false;
+ }
+ /* hidden items should be skipped if we only care about visible data,
+ * but we aren't interested in hidden stuff */
+ const bool skip_hidden = (filter_mode & ANIMFILTER_DATA_VISIBLE) &&
+ !(ads->filterflag & ADS_FILTER_INCL_HIDDEN);
+
+ if (GS(owner_id->name) == ID_OB) {
+ Object *ob = (Object *)owner_id;
+
+ /* only consider if F-Curve involves pose.bones */
+ if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones")) {
+ bPoseChannel *pchan;
+ char *bone_name;
+
+ /* get bone-name, and check if this bone is selected */
+ bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
+ pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
+ if (bone_name)
+ MEM_freeN(bone_name);
+
+ /* check whether to continue or skip */
+ if ((pchan) && (pchan->bone)) {
+ /* if only visible channels, skip if bone not visible unless user wants channels from hidden data too */
+ if (skip_hidden) {
+ bArmature *arm = (bArmature *)ob->data;
+
+ /* skipping - not visible on currently visible layers */
+ if ((arm->layer & pchan->bone->layer) == 0)
+ return true;
+ /* skipping - is currently hidden */
+ if (pchan->bone->flag & BONE_HIDDEN_P)
+ return true;
+ }
+
+ /* can only add this F-Curve if it is selected */
+ if (ads->filterflag & ADS_FILTER_ONLYSEL) {
+ if ((pchan->bone->flag & BONE_SELECTED) == 0)
+ return true;
+ }
+ }
+ }
+ }
+ else if (GS(owner_id->name) == ID_SCE) {
+ Scene *scene = (Scene *)owner_id;
+
+ /* only consider if F-Curve involves sequence_editor.sequences */
+ if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
+ Editing *ed = BKE_sequencer_editing_get(scene, false);
+ Sequence *seq = NULL;
+ char *seq_name;
+
+ if (ed) {
+ /* get strip name, and check if this strip is selected */
+ seq_name = BLI_str_quoted_substrN(fcu->rna_path, "sequences_all[");
+ seq = BKE_sequence_get_by_name(ed->seqbasep, seq_name, false);
+ if (seq_name)
+ MEM_freeN(seq_name);
+ }
+
+ /* can only add this F-Curve if it is selected */
+ if (ads->filterflag & ADS_FILTER_ONLYSEL) {
+ if ((seq == NULL) || (seq->flag & SELECT) == 0)
+ return true;
+ }
+ }
+ }
+ else if (GS(owner_id->name) == ID_NT) {
+ bNodeTree *ntree = (bNodeTree *)owner_id;
+
+ /* check for selected nodes */
+ if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) {
+ bNode *node;
+ char *node_name;
+
+ /* get strip name, and check if this strip is selected */
+ node_name = BLI_str_quoted_substrN(fcu->rna_path, "nodes[");
+ node = nodeFindNodebyName(ntree, node_name);
+ if (node_name)
+ MEM_freeN(node_name);
+
+ /* can only add this F-Curve if it is selected */
+ if (ads->filterflag & ADS_FILTER_ONLYSEL) {
+ if ((node) && (node->flag & NODE_SELECT) == 0)
+ return true;
+ }
+ }
+ }
+
+ return false;
}
/* Helper for name-based filtering - Perform "partial/fuzzy matches" (as in 80a7efd) */
static bool name_matches_dopesheet_filter(bDopeSheet *ads, char *name)
{
- if (ads->flag & ADS_FLAG_FUZZY_NAMES) {
- /* full fuzzy, multi-word, case insensitive matches */
- const size_t str_len = strlen(ads->searchstr);
- const int words_max = (str_len / 2) + 1;
-
- int (*words)[2] = BLI_array_alloca(words, words_max);
- const int words_len = BLI_string_find_split_words(ads->searchstr, str_len, ' ', words, words_max);
- bool found = false;
-
- /* match name against all search words */
- for (int index = 0; index < words_len; index++) {
- if (BLI_strncasestr(name, ads->searchstr + words[index][0], words[index][1])) {
- found = true;
- break;
- }
- }
-
- /* if we have a match somewhere, this returns true */
- return found;
- }
- else {
- /* fallback/default - just case insensitive, but starts from start of word */
- return BLI_strcasestr(name, ads->searchstr) != NULL;
- }
+ if (ads->flag & ADS_FLAG_FUZZY_NAMES) {
+ /* full fuzzy, multi-word, case insensitive matches */
+ const size_t str_len = strlen(ads->searchstr);
+ const int words_max = (str_len / 2) + 1;
+
+ int(*words)[2] = BLI_array_alloca(words, words_max);
+ const int words_len = BLI_string_find_split_words(
+ ads->searchstr, str_len, ' ', words, words_max);
+ bool found = false;
+
+ /* match name against all search words */
+ for (int index = 0; index < words_len; index++) {
+ if (BLI_strncasestr(name, ads->searchstr + words[index][0], words[index][1])) {
+ found = true;
+ break;
+ }
+ }
+
+ /* if we have a match somewhere, this returns true */
+ return found;
+ }
+ else {
+ /* fallback/default - just case insensitive, but starts from start of word */
+ return BLI_strcasestr(name, ads->searchstr) != NULL;
+ }
}
/* (Display-)Name-based F-Curve filtering
* NOTE: when this function returns true, the F-Curve is to be skipped
*/
-static bool skip_fcurve_with_name(bDopeSheet *ads, FCurve *fcu, eAnim_ChannelType channel_type, void *owner, ID *owner_id)
+static bool skip_fcurve_with_name(
+ bDopeSheet *ads, FCurve *fcu, eAnim_ChannelType channel_type, void *owner, ID *owner_id)
{
- bAnimListElem ale_dummy = {NULL};
- const bAnimChannelType *acf;
-
- /* create a dummy wrapper for the F-Curve, so we can get typeinfo for it */
- ale_dummy.type = channel_type;
- ale_dummy.owner = owner;
- ale_dummy.id = owner_id;
- ale_dummy.data = fcu;
-
- /* get type info for channel */
- acf = ANIM_channel_get_typeinfo(&ale_dummy);
- if (acf && acf->name) {
- char name[256]; /* hopefully this will be enough! */
-
- /* get name */
- acf->name(&ale_dummy, name);
-
- /* check for partial match with the match string, assuming case insensitive filtering
- * if match, this channel shouldn't be ignored!
- */
- return !name_matches_dopesheet_filter(ads, name);
- }
-
- /* just let this go... */
- return true;
+ bAnimListElem ale_dummy = {NULL};
+ const bAnimChannelType *acf;
+
+ /* create a dummy wrapper for the F-Curve, so we can get typeinfo for it */
+ ale_dummy.type = channel_type;
+ ale_dummy.owner = owner;
+ ale_dummy.id = owner_id;
+ ale_dummy.data = fcu;
+
+ /* get type info for channel */
+ acf = ANIM_channel_get_typeinfo(&ale_dummy);
+ if (acf && acf->name) {
+ char name[256]; /* hopefully this will be enough! */
+
+ /* get name */
+ acf->name(&ale_dummy, name);
+
+ /* check for partial match with the match string, assuming case insensitive filtering
+ * if match, this channel shouldn't be ignored!
+ */
+ return !name_matches_dopesheet_filter(ads, name);
+ }
+
+ /* just let this go... */
+ return true;
}
/**
@@ -1149,247 +1130,271 @@ static bool skip_fcurve_with_name(bDopeSheet *ads, FCurve *fcu, eAnim_ChannelTyp
*/
static bool fcurve_has_errors(FCurve *fcu)
{
- /* F-Curve disabled - path eval error */
- if (fcu->flag & FCURVE_DISABLED) {
- return true;
- }
-
- /* driver? */
- if (fcu->driver) {
- ChannelDriver *driver = fcu->driver;
- DriverVar *dvar;
-
- /* error flag on driver usually means that there is an error
- * BUT this may not hold with PyDrivers as this flag gets cleared
- * if no critical errors prevent the driver from working...
- */
- if (driver->flag & DRIVER_FLAG_INVALID)
- return true;
-
- /* check variables for other things that need linting... */
- // TODO: maybe it would be more efficient just to have a quick flag for this?
- for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
- DRIVER_TARGETS_USED_LOOPER_BEGIN(dvar)
- {
- if (dtar->flag & DTAR_FLAG_INVALID)
- return true;
- }
- DRIVER_TARGETS_LOOPER_END;
- }
- }
-
- /* no errors found */
- return false;
+ /* F-Curve disabled - path eval error */
+ if (fcu->flag & FCURVE_DISABLED) {
+ return true;
+ }
+
+ /* driver? */
+ if (fcu->driver) {
+ ChannelDriver *driver = fcu->driver;
+ DriverVar *dvar;
+
+ /* error flag on driver usually means that there is an error
+ * BUT this may not hold with PyDrivers as this flag gets cleared
+ * if no critical errors prevent the driver from working...
+ */
+ if (driver->flag & DRIVER_FLAG_INVALID)
+ return true;
+
+ /* check variables for other things that need linting... */
+ // TODO: maybe it would be more efficient just to have a quick flag for this?
+ for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+ DRIVER_TARGETS_USED_LOOPER_BEGIN (dvar) {
+ if (dtar->flag & DTAR_FLAG_INVALID)
+ return true;
+ }
+ DRIVER_TARGETS_LOOPER_END;
+ }
+ }
+
+ /* no errors found */
+ return false;
}
/* find the next F-Curve that is usable for inclusion */
-static FCurve *animfilter_fcurve_next(bDopeSheet *ads, FCurve *first, eAnim_ChannelType channel_type, int filter_mode, void *owner, ID *owner_id)
+static FCurve *animfilter_fcurve_next(bDopeSheet *ads,
+ FCurve *first,
+ eAnim_ChannelType channel_type,
+ int filter_mode,
+ void *owner,
+ ID *owner_id)
{
- bActionGroup *grp = (channel_type == ANIMTYPE_FCURVE) ? owner : NULL;
- FCurve *fcu = NULL;
-
- /* loop over F-Curves - assume that the caller of this has already checked that these should be included
- * NOTE: we need to check if the F-Curves belong to the same group, as this gets called for groups too...
- */
- for (fcu = first; ((fcu) && (fcu->grp == grp)); fcu = fcu->next) {
- /* special exception for Pose-Channel/Sequence-Strip/Node Based F-Curves:
- * - the 'Only Selected' and 'Include Hidden' data filters should be applied to sub-ID data which
- * can be independently selected/hidden, such as Pose-Channels, Sequence Strips, and Nodes.
- * Since these checks were traditionally done as first check for objects, we do the same here
- * - we currently use an 'approximate' method for getting these F-Curves that doesn't require
- * carefully checking the entire path
- * - this will also affect things like Drivers, and also works for Bone Constraints
- */
- if (ads && owner_id) {
- if ((filter_mode & ANIMFILTER_TMP_IGNORE_ONLYSEL) == 0) {
- if ((ads->filterflag & ADS_FILTER_ONLYSEL) || (ads->filterflag & ADS_FILTER_INCL_HIDDEN) == 0) {
- if (skip_fcurve_selected_data(ads, fcu, owner_id, filter_mode))
- continue;
- }
- }
- }
-
- /* only include if visible (Graph Editor check, not channels check) */
- if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || (fcu->flag & FCURVE_VISIBLE)) {
- /* only work with this channel and its subchannels if it is editable */
- if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_FCU(fcu)) {
- /* only include this curve if selected in a way consistent with the filtering requirements */
- if (ANIMCHANNEL_SELOK(SEL_FCU(fcu)) && ANIMCHANNEL_SELEDITOK(SEL_FCU(fcu))) {
- /* only include if this curve is active */
- if (!(filter_mode & ANIMFILTER_ACTIVE) || (fcu->flag & FCURVE_ACTIVE)) {
- /* name based filtering... */
- if ( ((ads) && (ads->searchstr[0] != '\0')) && (owner_id) ) {
- if (skip_fcurve_with_name(ads, fcu, channel_type, owner, owner_id))
- continue;
- }
-
- /* error-based filtering... */
- if ((ads) && (ads->filterflag & ADS_FILTER_ONLY_ERRORS)) {
- /* skip if no errors... */
- if (fcurve_has_errors(fcu) == false)
- continue;
- }
-
- /* this F-Curve can be used, so return it */
- return fcu;
- }
- }
- }
- }
- }
-
- /* no (more) F-Curves from the list are suitable... */
- return NULL;
+ bActionGroup *grp = (channel_type == ANIMTYPE_FCURVE) ? owner : NULL;
+ FCurve *fcu = NULL;
+
+ /* loop over F-Curves - assume that the caller of this has already checked that these should be included
+ * NOTE: we need to check if the F-Curves belong to the same group, as this gets called for groups too...
+ */
+ for (fcu = first; ((fcu) && (fcu->grp == grp)); fcu = fcu->next) {
+ /* special exception for Pose-Channel/Sequence-Strip/Node Based F-Curves:
+ * - the 'Only Selected' and 'Include Hidden' data filters should be applied to sub-ID data which
+ * can be independently selected/hidden, such as Pose-Channels, Sequence Strips, and Nodes.
+ * Since these checks were traditionally done as first check for objects, we do the same here
+ * - we currently use an 'approximate' method for getting these F-Curves that doesn't require
+ * carefully checking the entire path
+ * - this will also affect things like Drivers, and also works for Bone Constraints
+ */
+ if (ads && owner_id) {
+ if ((filter_mode & ANIMFILTER_TMP_IGNORE_ONLYSEL) == 0) {
+ if ((ads->filterflag & ADS_FILTER_ONLYSEL) ||
+ (ads->filterflag & ADS_FILTER_INCL_HIDDEN) == 0) {
+ if (skip_fcurve_selected_data(ads, fcu, owner_id, filter_mode))
+ continue;
+ }
+ }
+ }
+
+ /* only include if visible (Graph Editor check, not channels check) */
+ if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || (fcu->flag & FCURVE_VISIBLE)) {
+ /* only work with this channel and its subchannels if it is editable */
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_FCU(fcu)) {
+ /* only include this curve if selected in a way consistent with the filtering requirements */
+ if (ANIMCHANNEL_SELOK(SEL_FCU(fcu)) && ANIMCHANNEL_SELEDITOK(SEL_FCU(fcu))) {
+ /* only include if this curve is active */
+ if (!(filter_mode & ANIMFILTER_ACTIVE) || (fcu->flag & FCURVE_ACTIVE)) {
+ /* name based filtering... */
+ if (((ads) && (ads->searchstr[0] != '\0')) && (owner_id)) {
+ if (skip_fcurve_with_name(ads, fcu, channel_type, owner, owner_id))
+ continue;
+ }
+
+ /* error-based filtering... */
+ if ((ads) && (ads->filterflag & ADS_FILTER_ONLY_ERRORS)) {
+ /* skip if no errors... */
+ if (fcurve_has_errors(fcu) == false)
+ continue;
+ }
+
+ /* this F-Curve can be used, so return it */
+ return fcu;
+ }
+ }
+ }
+ }
+ }
+
+ /* no (more) F-Curves from the list are suitable... */
+ return NULL;
}
-static size_t animfilter_fcurves(ListBase *anim_data, bDopeSheet *ads,
- FCurve *first, eAnim_ChannelType fcurve_type,
+static size_t animfilter_fcurves(ListBase *anim_data,
+ bDopeSheet *ads,
+ FCurve *first,
+ eAnim_ChannelType fcurve_type,
int filter_mode,
- void *owner, ID *owner_id, ID *fcurve_owner_id)
+ void *owner,
+ ID *owner_id,
+ ID *fcurve_owner_id)
{
- FCurve *fcu;
- size_t items = 0;
-
- /* loop over every F-Curve able to be included
- * - this for-loop works like this:
- * 1) the starting F-Curve is assigned to the fcu pointer so that we have a starting point to search from
- * 2) the first valid F-Curve to start from (which may include the one given as 'first') in the remaining
- * list of F-Curves is found, and verified to be non-null
- * 3) the F-Curve referenced by fcu pointer is added to the list
- * 4) the fcu pointer is set to the F-Curve after the one we just added, so that we can keep going through
- * the rest of the F-Curve list without an eternal loop. Back to step 2 :)
- */
- for (fcu = first; ( (fcu = animfilter_fcurve_next(ads, fcu, fcurve_type, filter_mode, owner, owner_id)) ); fcu = fcu->next) {
- if (UNLIKELY(fcurve_type == ANIMTYPE_NLACURVE)) {
- /* NLA Control Curve - Basically the same as normal F-Curves,
- * except we need to set some stuff differently */
- ANIMCHANNEL_NEW_CHANNEL_FULL(fcu, ANIMTYPE_NLACURVE, owner_id, fcurve_owner_id, {
- ale->owner = owner; /* strip */
- ale->adt = NULL; /* to prevent time mapping from causing problems */
- });
- }
- else {
- /* Normal FCurve */
- ANIMCHANNEL_NEW_CHANNEL(fcu, ANIMTYPE_FCURVE, owner_id, fcurve_owner_id);
- }
- }
-
- /* return the number of items added to the list */
- return items;
+ FCurve *fcu;
+ size_t items = 0;
+
+ /* loop over every F-Curve able to be included
+ * - this for-loop works like this:
+ * 1) the starting F-Curve is assigned to the fcu pointer so that we have a starting point to search from
+ * 2) the first valid F-Curve to start from (which may include the one given as 'first') in the remaining
+ * list of F-Curves is found, and verified to be non-null
+ * 3) the F-Curve referenced by fcu pointer is added to the list
+ * 4) the fcu pointer is set to the F-Curve after the one we just added, so that we can keep going through
+ * the rest of the F-Curve list without an eternal loop. Back to step 2 :)
+ */
+ for (fcu = first;
+ ((fcu = animfilter_fcurve_next(ads, fcu, fcurve_type, filter_mode, owner, owner_id)));
+ fcu = fcu->next) {
+ if (UNLIKELY(fcurve_type == ANIMTYPE_NLACURVE)) {
+ /* NLA Control Curve - Basically the same as normal F-Curves,
+ * except we need to set some stuff differently */
+ ANIMCHANNEL_NEW_CHANNEL_FULL(fcu, ANIMTYPE_NLACURVE, owner_id, fcurve_owner_id, {
+ ale->owner = owner; /* strip */
+ ale->adt = NULL; /* to prevent time mapping from causing problems */
+ });
+ }
+ else {
+ /* Normal FCurve */
+ ANIMCHANNEL_NEW_CHANNEL(fcu, ANIMTYPE_FCURVE, owner_id, fcurve_owner_id);
+ }
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
-static size_t animfilter_act_group(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAction *act, bActionGroup *agrp, int filter_mode, ID *owner_id)
+static size_t animfilter_act_group(bAnimContext *ac,
+ ListBase *anim_data,
+ bDopeSheet *ads,
+ bAction *act,
+ bActionGroup *agrp,
+ int filter_mode,
+ ID *owner_id)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
- //int ofilter = filter_mode;
-
- /* if we care about the selection status of the channels,
- * but the group isn't expanded (1)...
- * (1) this only matters if we actually care about the hierarchy though.
- * - Hierarchy matters: this hack should be applied
- * - Hierarchy ignored: cases like [#21276] won't work properly, unless we skip this hack
- */
- if (
- /* care about hierarchy but group isn't expanded */
- ((filter_mode & ANIMFILTER_LIST_VISIBLE) && EXPANDED_AGRP(ac, agrp) == 0) &&
- /* care about selection status */
- (filter_mode & (ANIMFILTER_SEL | ANIMFILTER_UNSEL)) )
- {
- /* if the group itself isn't selected appropriately, we shouldn't consider it's children either */
- if (ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) == 0)
- return 0;
-
- /* if we're still here, then the selection status of the curves within this group should not matter,
- * since this creates too much overhead for animators (i.e. making a slow workflow)
- *
- * Tools affected by this at time of coding (2010 Feb 09):
- * - inserting keyframes on selected channels only
- * - pasting keyframes
- * - creating ghost curves in Graph Editor
- */
- filter_mode &= ~(ANIMFILTER_SEL | ANIMFILTER_UNSEL | ANIMFILTER_LIST_VISIBLE);
- }
-
- /* add grouped F-Curves */
- BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_AGRP(ac, agrp))
- {
- /* special filter so that we can get just the F-Curves within the active group */
- if (!(filter_mode & ANIMFILTER_ACTGROUPED) || (agrp->flag & AGRP_ACTIVE)) {
- /* for the Graph Editor, curves may be set to not be visible in the view to lessen
- * clutter, but to do this, we need to check that the group doesn't have it's
- * not-visible flag set preventing all its sub-curves to be shown
- */
- if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || !(agrp->flag & AGRP_NOTVISIBLE)) {
- /* group must be editable for its children to be editable (if we care about this) */
- if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {
- /* get first F-Curve which can be used here */
- FCurve *first_fcu = animfilter_fcurve_next(ads, agrp->channels.first, ANIMTYPE_FCURVE, filter_mode, agrp, owner_id);
-
- /* filter list, starting from this F-Curve */
- tmp_items += animfilter_fcurves(&tmp_data, ads, first_fcu, ANIMTYPE_FCURVE, filter_mode, agrp, owner_id, &act->id);
- }
- }
- }
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* add this group as a channel first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* restore original filter mode so that this next step works ok... */
- //filter_mode = ofilter;
-
- /* filter selection of channel specially here again,
- * since may be open and not subject to previous test */
- if (ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) ) {
- ANIMCHANNEL_NEW_CHANNEL(agrp, ANIMTYPE_GROUP, owner_id, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- /* return the number of items added to the list */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+ //int ofilter = filter_mode;
+
+ /* if we care about the selection status of the channels,
+ * but the group isn't expanded (1)...
+ * (1) this only matters if we actually care about the hierarchy though.
+ * - Hierarchy matters: this hack should be applied
+ * - Hierarchy ignored: cases like [#21276] won't work properly, unless we skip this hack
+ */
+ if (
+ /* care about hierarchy but group isn't expanded */
+ ((filter_mode & ANIMFILTER_LIST_VISIBLE) && EXPANDED_AGRP(ac, agrp) == 0) &&
+ /* care about selection status */
+ (filter_mode & (ANIMFILTER_SEL | ANIMFILTER_UNSEL))) {
+ /* if the group itself isn't selected appropriately, we shouldn't consider it's children either */
+ if (ANIMCHANNEL_SELOK(SEL_AGRP(agrp)) == 0)
+ return 0;
+
+ /* if we're still here, then the selection status of the curves within this group should not matter,
+ * since this creates too much overhead for animators (i.e. making a slow workflow)
+ *
+ * Tools affected by this at time of coding (2010 Feb 09):
+ * - inserting keyframes on selected channels only
+ * - pasting keyframes
+ * - creating ghost curves in Graph Editor
+ */
+ filter_mode &= ~(ANIMFILTER_SEL | ANIMFILTER_UNSEL | ANIMFILTER_LIST_VISIBLE);
+ }
+
+ /* add grouped F-Curves */
+ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_AGRP(ac, agrp))
+ {
+ /* special filter so that we can get just the F-Curves within the active group */
+ if (!(filter_mode & ANIMFILTER_ACTGROUPED) || (agrp->flag & AGRP_ACTIVE)) {
+ /* for the Graph Editor, curves may be set to not be visible in the view to lessen
+ * clutter, but to do this, we need to check that the group doesn't have it's
+ * not-visible flag set preventing all its sub-curves to be shown
+ */
+ if (!(filter_mode & ANIMFILTER_CURVE_VISIBLE) || !(agrp->flag & AGRP_NOTVISIBLE)) {
+ /* group must be editable for its children to be editable (if we care about this) */
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_AGRP(agrp)) {
+ /* get first F-Curve which can be used here */
+ FCurve *first_fcu = animfilter_fcurve_next(
+ ads, agrp->channels.first, ANIMTYPE_FCURVE, filter_mode, agrp, owner_id);
+
+ /* filter list, starting from this F-Curve */
+ tmp_items += animfilter_fcurves(
+ &tmp_data, ads, first_fcu, ANIMTYPE_FCURVE, filter_mode, agrp, owner_id, &act->id);
+ }
+ }
+ }
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* add this group as a channel first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* restore original filter mode so that this next step works ok... */
+ //filter_mode = ofilter;
+
+ /* filter selection of channel specially here again,
+ * since may be open and not subject to previous test */
+ if (ANIMCHANNEL_SELOK(SEL_AGRP(agrp))) {
+ ANIMCHANNEL_NEW_CHANNEL(agrp, ANIMTYPE_GROUP, owner_id, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
-static size_t animfilter_action(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAction *act, int filter_mode, ID *owner_id)
+static size_t animfilter_action(bAnimContext *ac,
+ ListBase *anim_data,
+ bDopeSheet *ads,
+ bAction *act,
+ int filter_mode,
+ ID *owner_id)
{
- bActionGroup *agrp;
- FCurve *lastchan = NULL;
- size_t items = 0;
-
- /* don't include anything from this action if it is linked in from another file,
- * and we're getting stuff for editing...
- */
- if ((filter_mode & ANIMFILTER_FOREDIT) && ID_IS_LINKED(act))
- return 0;
-
- /* do groups */
- // TODO: do nested groups?
- for (agrp = act->groups.first; agrp; agrp = agrp->next) {
- /* store reference to last channel of group */
- if (agrp->channels.last)
- lastchan = agrp->channels.last;
-
- /* action group's channels */
- items += animfilter_act_group(ac, anim_data, ads, act, agrp, filter_mode, owner_id);
- }
-
- /* un-grouped F-Curves (only if we're not only considering those channels in the active group) */
- if (!(filter_mode & ANIMFILTER_ACTGROUPED)) {
- FCurve *firstfcu = (lastchan) ? (lastchan->next) : (act->curves.first);
- items += animfilter_fcurves(anim_data, ads, firstfcu, ANIMTYPE_FCURVE, filter_mode, NULL, owner_id, &act->id);
- }
-
- /* return the number of items added to the list */
- return items;
+ bActionGroup *agrp;
+ FCurve *lastchan = NULL;
+ size_t items = 0;
+
+ /* don't include anything from this action if it is linked in from another file,
+ * and we're getting stuff for editing...
+ */
+ if ((filter_mode & ANIMFILTER_FOREDIT) && ID_IS_LINKED(act))
+ return 0;
+
+ /* do groups */
+ // TODO: do nested groups?
+ for (agrp = act->groups.first; agrp; agrp = agrp->next) {
+ /* store reference to last channel of group */
+ if (agrp->channels.last)
+ lastchan = agrp->channels.last;
+
+ /* action group's channels */
+ items += animfilter_act_group(ac, anim_data, ads, act, agrp, filter_mode, owner_id);
+ }
+
+ /* un-grouped F-Curves (only if we're not only considering those channels in the active group) */
+ if (!(filter_mode & ANIMFILTER_ACTGROUPED)) {
+ FCurve *firstfcu = (lastchan) ? (lastchan->next) : (act->curves.first);
+ items += animfilter_fcurves(
+ anim_data, ads, firstfcu, ANIMTYPE_FCURVE, filter_mode, NULL, owner_id, &act->id);
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
/* Include NLA-Data for NLA-Editor:
@@ -1400,863 +1405,916 @@ static size_t animfilter_action(bAnimContext *ac, ListBase *anim_data, bDopeShee
* - for normal filtering (i.e. for editing), we only need the NLA-tracks but they can be in 'normal' evaluation
* order, i.e. first to last. Otherwise, some tools may get screwed up.
*/
-static size_t animfilter_nla(bAnimContext *UNUSED(ac), ListBase *anim_data, bDopeSheet *ads, AnimData *adt, int filter_mode, ID *owner_id)
+static size_t animfilter_nla(bAnimContext *UNUSED(ac),
+ ListBase *anim_data,
+ bDopeSheet *ads,
+ AnimData *adt,
+ int filter_mode,
+ ID *owner_id)
{
- NlaTrack *nlt;
- NlaTrack *first = NULL, *next = NULL;
- size_t items = 0;
-
- /* if showing channels, include active action */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* if NLA action-line filtering is off, don't show unless there are keyframes,
- * in order to keep things more compact for doing transforms
- */
- if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) || (adt->action)) {
- /* there isn't really anything editable here, so skip if need editable */
- if ((filter_mode & ANIMFILTER_FOREDIT) == 0) {
- /* just add the action track now (this MUST appear for drawing)
- * - as AnimData may not have an action, we pass a dummy pointer just to get the list elem created, then
- * overwrite this with the real value - REVIEW THIS...
- */
- ANIMCHANNEL_NEW_CHANNEL_FULL(
- (void *)(&adt->action), ANIMTYPE_NLAACTION, owner_id, NULL,
- {
- ale->data = adt->action ? adt->action : NULL;
- });
- }
- }
-
- /* first track to include will be the last one if we're filtering by channels */
- first = adt->nla_tracks.last;
- }
- else {
- /* first track to include will the first one (as per normal) */
- first = adt->nla_tracks.first;
- }
-
- /* loop over NLA Tracks - assume that the caller of this has already checked that these should be included */
- for (nlt = first; nlt; nlt = next) {
- /* 'next' NLA-Track to use depends on whether we're filtering for drawing or not */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS)
- next = nlt->prev;
- else
- next = nlt->next;
-
- /* if we're in NLA-tweakmode, don't show this track if it was disabled (due to tweaking) for now
- * - active track should still get shown though (even though it has disabled flag set)
- */
- // FIXME: the channels after should still get drawn, just 'differently', and after an active-action channel
- if ((adt->flag & ADT_NLA_EDIT_ON) && (nlt->flag & NLATRACK_DISABLED) && (adt->act_track != nlt))
- continue;
-
- /* only work with this channel and its subchannels if it is editable */
- if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_NLT(nlt)) {
- /* only include this track if selected in a way consistent with the filtering requirements */
- if (ANIMCHANNEL_SELOK(SEL_NLT(nlt))) {
- /* only include if this track is active */
- if (!(filter_mode & ANIMFILTER_ACTIVE) || (nlt->flag & NLATRACK_ACTIVE)) {
- /* name based filtering... */
- if (((ads) && (ads->searchstr[0] != '\0')) && (owner_id)) {
- bool track_ok = false, strip_ok = false;
-
- /* check if the name of the track, or the strips it has are ok... */
- track_ok = name_matches_dopesheet_filter(ads, nlt->name);
-
- if (track_ok == false) {
- NlaStrip *strip;
- for (strip = nlt->strips.first; strip; strip = strip->next) {
- if (name_matches_dopesheet_filter(ads, strip->name)) {
- strip_ok = true;
- break;
- }
- }
- }
-
- /* skip if both fail this test... */
- if (!track_ok && !strip_ok) {
- continue;
- }
- }
-
- /* add the track now that it has passed all our tests */
- ANIMCHANNEL_NEW_CHANNEL(nlt, ANIMTYPE_NLATRACK, owner_id, NULL);
- }
- }
- }
- }
-
- /* return the number of items added to the list */
- return items;
+ NlaTrack *nlt;
+ NlaTrack *first = NULL, *next = NULL;
+ size_t items = 0;
+
+ /* if showing channels, include active action */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* if NLA action-line filtering is off, don't show unless there are keyframes,
+ * in order to keep things more compact for doing transforms
+ */
+ if (!(ads->filterflag & ADS_FILTER_NLA_NOACT) || (adt->action)) {
+ /* there isn't really anything editable here, so skip if need editable */
+ if ((filter_mode & ANIMFILTER_FOREDIT) == 0) {
+ /* just add the action track now (this MUST appear for drawing)
+ * - as AnimData may not have an action, we pass a dummy pointer just to get the list elem created, then
+ * overwrite this with the real value - REVIEW THIS...
+ */
+ ANIMCHANNEL_NEW_CHANNEL_FULL((void *)(&adt->action), ANIMTYPE_NLAACTION, owner_id, NULL, {
+ ale->data = adt->action ? adt->action : NULL;
+ });
+ }
+ }
+
+ /* first track to include will be the last one if we're filtering by channels */
+ first = adt->nla_tracks.last;
+ }
+ else {
+ /* first track to include will the first one (as per normal) */
+ first = adt->nla_tracks.first;
+ }
+
+ /* loop over NLA Tracks - assume that the caller of this has already checked that these should be included */
+ for (nlt = first; nlt; nlt = next) {
+ /* 'next' NLA-Track to use depends on whether we're filtering for drawing or not */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS)
+ next = nlt->prev;
+ else
+ next = nlt->next;
+
+ /* if we're in NLA-tweakmode, don't show this track if it was disabled (due to tweaking) for now
+ * - active track should still get shown though (even though it has disabled flag set)
+ */
+ // FIXME: the channels after should still get drawn, just 'differently', and after an active-action channel
+ if ((adt->flag & ADT_NLA_EDIT_ON) && (nlt->flag & NLATRACK_DISABLED) &&
+ (adt->act_track != nlt))
+ continue;
+
+ /* only work with this channel and its subchannels if it is editable */
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_NLT(nlt)) {
+ /* only include this track if selected in a way consistent with the filtering requirements */
+ if (ANIMCHANNEL_SELOK(SEL_NLT(nlt))) {
+ /* only include if this track is active */
+ if (!(filter_mode & ANIMFILTER_ACTIVE) || (nlt->flag & NLATRACK_ACTIVE)) {
+ /* name based filtering... */
+ if (((ads) && (ads->searchstr[0] != '\0')) && (owner_id)) {
+ bool track_ok = false, strip_ok = false;
+
+ /* check if the name of the track, or the strips it has are ok... */
+ track_ok = name_matches_dopesheet_filter(ads, nlt->name);
+
+ if (track_ok == false) {
+ NlaStrip *strip;
+ for (strip = nlt->strips.first; strip; strip = strip->next) {
+ if (name_matches_dopesheet_filter(ads, strip->name)) {
+ strip_ok = true;
+ break;
+ }
+ }
+ }
+
+ /* skip if both fail this test... */
+ if (!track_ok && !strip_ok) {
+ continue;
+ }
+ }
+
+ /* add the track now that it has passed all our tests */
+ ANIMCHANNEL_NEW_CHANNEL(nlt, ANIMTYPE_NLATRACK, owner_id, NULL);
+ }
+ }
+ }
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
/* Include the control FCurves per NLA Strip in the channel list
* NOTE: This is includes the expander too...
*/
-static size_t animfilter_nla_controls(ListBase *anim_data, bDopeSheet *ads, AnimData *adt, int filter_mode, ID *owner_id)
+static size_t animfilter_nla_controls(
+ ListBase *anim_data, bDopeSheet *ads, AnimData *adt, int filter_mode, ID *owner_id)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
-
- /* add control curves from each NLA strip... */
- /* NOTE: ANIMTYPE_FCURVES are created here, to avoid duplicating the code needed */
- BEGIN_ANIMFILTER_SUBCHANNELS(((adt->flag & ADT_NLA_SKEYS_COLLAPSED) == 0))
- {
- NlaTrack *nlt;
- NlaStrip *strip;
-
- /* for now, we only go one level deep - so controls on grouped FCurves are not handled */
- for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
- for (strip = nlt->strips.first; strip; strip = strip->next) {
- /* pass strip as the "owner", so that the name lookups (used while filtering) will resolve */
- /* NLA tracks are coming from AnimData, so owner of f-curves
- * is the same as owner of animation data. */
- tmp_items += animfilter_fcurves(&tmp_data, ads, strip->fcurves.first, ANIMTYPE_NLACURVE,
- filter_mode, strip, owner_id, owner_id);
- }
- }
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* add the expander as a channel first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* currently these channels cannot be selected, so they should be skipped */
- if ((filter_mode & (ANIMFILTER_SEL | ANIMFILTER_UNSEL)) == 0) {
- ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_NLACONTROLS, owner_id, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- /* return the number of items added to the list */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* add control curves from each NLA strip... */
+ /* NOTE: ANIMTYPE_FCURVES are created here, to avoid duplicating the code needed */
+ BEGIN_ANIMFILTER_SUBCHANNELS(((adt->flag & ADT_NLA_SKEYS_COLLAPSED) == 0))
+ {
+ NlaTrack *nlt;
+ NlaStrip *strip;
+
+ /* for now, we only go one level deep - so controls on grouped FCurves are not handled */
+ for (nlt = adt->nla_tracks.first; nlt; nlt = nlt->next) {
+ for (strip = nlt->strips.first; strip; strip = strip->next) {
+ /* pass strip as the "owner", so that the name lookups (used while filtering) will resolve */
+ /* NLA tracks are coming from AnimData, so owner of f-curves
+ * is the same as owner of animation data. */
+ tmp_items += animfilter_fcurves(&tmp_data,
+ ads,
+ strip->fcurves.first,
+ ANIMTYPE_NLACURVE,
+ filter_mode,
+ strip,
+ owner_id,
+ owner_id);
+ }
+ }
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* add the expander as a channel first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* currently these channels cannot be selected, so they should be skipped */
+ if ((filter_mode & (ANIMFILTER_SEL | ANIMFILTER_UNSEL)) == 0) {
+ ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_NLACONTROLS, owner_id, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
/* determine what animation data from AnimData block should get displayed */
-static size_t animfilter_block_data(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *id, int filter_mode)
+static size_t animfilter_block_data(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *id, int filter_mode)
{
- AnimData *adt = BKE_animdata_from_id(id);
- size_t items = 0;
-
- /* image object datablocks have no anim-data so check for NULL */
- if (adt) {
- IdAdtTemplate *iat = (IdAdtTemplate *)id;
-
- /* NOTE: this macro is used instead of inlining the logic here, since this sort of filtering is still needed
- * in a few places in the rest of the code still - notably for the few cases where special mode-based
- * different types of data expanders are required.
- */
- ANIMDATA_FILTER_CASES(
- iat,
- { /* AnimData */
- /* specifically filter animdata block */
- if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(adt)) ) {
- ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id, NULL);
- }
- },
- { /* NLA */
- items += animfilter_nla(ac, anim_data, ads, adt, filter_mode, id);
- },
- { /* Drivers */
- items += animfilter_fcurves(anim_data, ads, adt->drivers.first, ANIMTYPE_FCURVE,
- filter_mode, NULL, id, id);
- },
- { /* NLA Control Keyframes */
- items += animfilter_nla_controls(anim_data, ads, adt, filter_mode, id);
- },
- { /* Keyframes */
- items += animfilter_action(ac, anim_data, ads, adt->action, filter_mode, id);
- }
- );
- }
-
- return items;
+ AnimData *adt = BKE_animdata_from_id(id);
+ size_t items = 0;
+
+ /* image object datablocks have no anim-data so check for NULL */
+ if (adt) {
+ IdAdtTemplate *iat = (IdAdtTemplate *)id;
+
+ /* NOTE: this macro is used instead of inlining the logic here, since this sort of filtering is still needed
+ * in a few places in the rest of the code still - notably for the few cases where special mode-based
+ * different types of data expanders are required.
+ */
+ ANIMDATA_FILTER_CASES(
+ iat,
+ { /* AnimData */
+ /* specifically filter animdata block */
+ if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(adt))) {
+ ANIMCHANNEL_NEW_CHANNEL(adt, ANIMTYPE_ANIMDATA, id, NULL);
+ }
+ },
+ { /* NLA */
+ items += animfilter_nla(ac, anim_data, ads, adt, filter_mode, id);
+ },
+ { /* Drivers */
+ items += animfilter_fcurves(
+ anim_data, ads, adt->drivers.first, ANIMTYPE_FCURVE, filter_mode, NULL, id, id);
+ },
+ { /* NLA Control Keyframes */
+ items += animfilter_nla_controls(anim_data, ads, adt, filter_mode, id);
+ },
+ { /* Keyframes */
+ items += animfilter_action(ac, anim_data, ads, adt->action, filter_mode, id);
+ });
+ }
+
+ return items;
}
-
-
/* Include ShapeKey Data for ShapeKey Editor */
-static size_t animdata_filter_shapekey(bAnimContext *ac, ListBase *anim_data, Key *key, int filter_mode)
+static size_t animdata_filter_shapekey(bAnimContext *ac,
+ ListBase *anim_data,
+ Key *key,
+ int filter_mode)
{
- size_t items = 0;
-
- /* check if channels or only F-Curves */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- KeyBlock *kb;
-
- /* loop through the channels adding ShapeKeys as appropriate */
- for (kb = key->block.first; kb; kb = kb->next) {
- /* skip the first one, since that's the non-animatable basis */
- if (kb == key->block.first) continue;
-
- /* only work with this channel and its subchannels if it is editable */
- if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_SHAPEKEY(kb)) {
- /* only include this track if selected in a way consistent with the filtering requirements */
- if (ANIMCHANNEL_SELOK(SEL_SHAPEKEY(kb)) ) {
- // TODO: consider 'active' too?
-
- /* owner-id here must be key so that the F-Curve can be resolved... */
- ANIMCHANNEL_NEW_CHANNEL(kb, ANIMTYPE_SHAPEKEY, key, NULL);
- }
- }
- }
- }
- else {
- /* just use the action associated with the shapekey */
- // TODO: somehow manage to pass dopesheet info down here too?
- if (key->adt) {
- if (filter_mode & ANIMFILTER_ANIMDATA) {
- if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(key->adt)) ) {
- ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key, NULL);
- }
- }
- else if (key->adt->action) {
- items = animfilter_action(ac, anim_data, NULL, key->adt->action, filter_mode, (ID *)key);
- }
- }
- }
-
- /* return the number of items added to the list */
- return items;
+ size_t items = 0;
+
+ /* check if channels or only F-Curves */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ KeyBlock *kb;
+
+ /* loop through the channels adding ShapeKeys as appropriate */
+ for (kb = key->block.first; kb; kb = kb->next) {
+ /* skip the first one, since that's the non-animatable basis */
+ if (kb == key->block.first)
+ continue;
+
+ /* only work with this channel and its subchannels if it is editable */
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_SHAPEKEY(kb)) {
+ /* only include this track if selected in a way consistent with the filtering requirements */
+ if (ANIMCHANNEL_SELOK(SEL_SHAPEKEY(kb))) {
+ // TODO: consider 'active' too?
+
+ /* owner-id here must be key so that the F-Curve can be resolved... */
+ ANIMCHANNEL_NEW_CHANNEL(kb, ANIMTYPE_SHAPEKEY, key, NULL);
+ }
+ }
+ }
+ }
+ else {
+ /* just use the action associated with the shapekey */
+ // TODO: somehow manage to pass dopesheet info down here too?
+ if (key->adt) {
+ if (filter_mode & ANIMFILTER_ANIMDATA) {
+ if (ANIMCHANNEL_SELOK(SEL_ANIMDATA(key->adt))) {
+ ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, key, NULL);
+ }
+ }
+ else if (key->adt->action) {
+ items = animfilter_action(ac, anim_data, NULL, key->adt->action, filter_mode, (ID *)key);
+ }
+ }
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
/* Helper for Grease Pencil - layers within a datablock */
-static size_t animdata_filter_gpencil_layers_data(ListBase *anim_data, bDopeSheet *ads, bGPdata *gpd, int filter_mode)
+static size_t animdata_filter_gpencil_layers_data(ListBase *anim_data,
+ bDopeSheet *ads,
+ bGPdata *gpd,
+ int filter_mode)
{
- bGPDlayer *gpl;
- size_t items = 0;
-
- /* loop over layers as the conditions are acceptable (top-Down order) */
- for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) {
- /* only if selected */
- if (ANIMCHANNEL_SELOK(SEL_GPL(gpl)) ) {
- /* only if editable */
- if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_GPL(gpl)) {
- /* active... */
- if (!(filter_mode & ANIMFILTER_ACTIVE) || (gpl->flag & GP_LAYER_ACTIVE)) {
- /* skip layer if the name doesn't match the filter string */
- if ((ads) && (ads->searchstr[0] != '\0')) {
- if (name_matches_dopesheet_filter(ads, gpl->info) == false)
- continue;
- }
- /* add to list */
- ANIMCHANNEL_NEW_CHANNEL(gpl, ANIMTYPE_GPLAYER, gpd, NULL);
- }
- }
- }
- }
-
- return items;
+ bGPDlayer *gpl;
+ size_t items = 0;
+
+ /* loop over layers as the conditions are acceptable (top-Down order) */
+ for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) {
+ /* only if selected */
+ if (ANIMCHANNEL_SELOK(SEL_GPL(gpl))) {
+ /* only if editable */
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_GPL(gpl)) {
+ /* active... */
+ if (!(filter_mode & ANIMFILTER_ACTIVE) || (gpl->flag & GP_LAYER_ACTIVE)) {
+ /* skip layer if the name doesn't match the filter string */
+ if ((ads) && (ads->searchstr[0] != '\0')) {
+ if (name_matches_dopesheet_filter(ads, gpl->info) == false)
+ continue;
+ }
+ /* add to list */
+ ANIMCHANNEL_NEW_CHANNEL(gpl, ANIMTYPE_GPLAYER, gpd, NULL);
+ }
+ }
+ }
+ }
+
+ return items;
}
/* Helper for Grease Pencil - Grease Pencil datablock - GP Frames */
-static size_t animdata_filter_gpencil_data(ListBase *anim_data, bDopeSheet *ads, bGPdata *gpd, int filter_mode)
+static size_t animdata_filter_gpencil_data(ListBase *anim_data,
+ bDopeSheet *ads,
+ bGPdata *gpd,
+ int filter_mode)
{
- size_t items = 0;
-
- /* When asked from "AnimData" blocks (i.e. the top-level containers for normal animation),
- * for convenience, this will return GP Datablocks instead. This may cause issues down
- * the track, but for now, this will do...
- */
- if (filter_mode & ANIMFILTER_ANIMDATA) {
- /* just add GPD as a channel - this will add everything needed */
- ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, gpd, NULL);
- }
- else {
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
-
- /* add gpencil animation channels */
- BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd))
- {
- tmp_items += animdata_filter_gpencil_layers_data(&tmp_data, ads, gpd, filter_mode);
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include data-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* add gpd as channel too (if for drawing, and it has layers) */
- ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL, NULL);
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
- }
-
- return items;
+ size_t items = 0;
+
+ /* When asked from "AnimData" blocks (i.e. the top-level containers for normal animation),
+ * for convenience, this will return GP Datablocks instead. This may cause issues down
+ * the track, but for now, this will do...
+ */
+ if (filter_mode & ANIMFILTER_ANIMDATA) {
+ /* just add GPD as a channel - this will add everything needed */
+ ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, gpd, NULL);
+ }
+ else {
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+
+ /* add gpencil animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd))
+ {
+ tmp_items += animdata_filter_gpencil_layers_data(&tmp_data, ads, gpd, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* add gpd as channel too (if for drawing, and it has layers) */
+ ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_GPDATABLOCK, NULL, NULL);
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+ }
+
+ return items;
}
/* Grab all Grease Pencil datablocks in file */
// TODO: should this be amalgamated with the dopesheet filtering code?
-static size_t animdata_filter_gpencil(bAnimContext *ac, ListBase *anim_data, void *UNUSED(data), int filter_mode)
+static size_t animdata_filter_gpencil(bAnimContext *ac,
+ ListBase *anim_data,
+ void *UNUSED(data),
+ int filter_mode)
{
- bDopeSheet *ads = ac->ads;
- size_t items = 0;
-
- if (ads->filterflag & ADS_FILTER_GP_3DONLY) {
- Scene *scene = (Scene *)ads->source;
- ViewLayer *view_layer = (ViewLayer *)ac->view_layer;
- Base *base;
-
- /* Active scene's GPencil block first - No parent item needed... */
- if (scene->gpd) {
- items += animdata_filter_gpencil_data(anim_data, ads, scene->gpd, filter_mode);
- }
-
- /* Objects in the scene */
- for (base = view_layer->object_bases.first; base; base = base->next) {
- /* Only consider this object if it has got some GP data (saving on all the other tests) */
- if (base->object && (base->object->type == OB_GPENCIL)) {
- Object *ob = base->object;
-
- /* firstly, check if object can be included, by the following factors:
- * - if only visible, must check for layer and also viewport visibility
- * --> while tools may demand only visible, user setting takes priority
- * as user option controls whether sets of channels get included while
- * tool-flag takes into account collapsed/open channels too
- * - if only selected, must check if object is selected
- * - there must be animation data to edit (this is done recursively as we
- * try to add the channels)
- */
- if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
- /* layer visibility - we check both object and base, since these may not be in sync yet */
- if ((base->flag & BASE_VISIBLE) == 0) continue;
-
- /* outliner restrict-flag */
- if (ob->restrictflag & OB_RESTRICT_VIEW) continue;
- }
-
- /* check selection and object type filters */
- if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & BASE_SELECTED) /*|| (base == scene->basact)*/) ) {
- /* only selected should be shown */
- continue;
- }
-
- /* check if object belongs to the filtering group if option to filter
- * objects by the grouped status is on
- * - used to ease the process of doing multiple-character choreographies
- */
- if (ads->filter_grp != NULL) {
- if (BKE_collection_has_object_recursive(ads->filter_grp, ob) == 0)
- continue;
- }
-
- /* finally, include this object's grease pencil datablock */
- /* XXX: Should we store these under expanders per item? */
- items += animdata_filter_gpencil_data(anim_data, ads, ob->data, filter_mode);
- }
- }
- }
- else {
- bGPdata *gpd;
-
- /* Grab all Grease Pencil datablocks directly from main,
- * but only those that seem to be useful somewhere */
- for (gpd = ac->bmain->gpencils.first; gpd; gpd = gpd->id.next) {
- /* only show if gpd is used by something... */
- if (ID_REAL_USERS(gpd) < 1)
- continue;
-
- /* add GP frames from this datablock */
- items += animdata_filter_gpencil_data(anim_data, ads, gpd, filter_mode);
- }
- }
-
- /* return the number of items added to the list */
- return items;
+ bDopeSheet *ads = ac->ads;
+ size_t items = 0;
+
+ if (ads->filterflag & ADS_FILTER_GP_3DONLY) {
+ Scene *scene = (Scene *)ads->source;
+ ViewLayer *view_layer = (ViewLayer *)ac->view_layer;
+ Base *base;
+
+ /* Active scene's GPencil block first - No parent item needed... */
+ if (scene->gpd) {
+ items += animdata_filter_gpencil_data(anim_data, ads, scene->gpd, filter_mode);
+ }
+
+ /* Objects in the scene */
+ for (base = view_layer->object_bases.first; base; base = base->next) {
+ /* Only consider this object if it has got some GP data (saving on all the other tests) */
+ if (base->object && (base->object->type == OB_GPENCIL)) {
+ Object *ob = base->object;
+
+ /* firstly, check if object can be included, by the following factors:
+ * - if only visible, must check for layer and also viewport visibility
+ * --> while tools may demand only visible, user setting takes priority
+ * as user option controls whether sets of channels get included while
+ * tool-flag takes into account collapsed/open channels too
+ * - if only selected, must check if object is selected
+ * - there must be animation data to edit (this is done recursively as we
+ * try to add the channels)
+ */
+ if ((filter_mode & ANIMFILTER_DATA_VISIBLE) &&
+ !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
+ /* layer visibility - we check both object and base, since these may not be in sync yet */
+ if ((base->flag & BASE_VISIBLE) == 0)
+ continue;
+
+ /* outliner restrict-flag */
+ if (ob->restrictflag & OB_RESTRICT_VIEW)
+ continue;
+ }
+
+ /* check selection and object type filters */
+ if ((ads->filterflag & ADS_FILTER_ONLYSEL) &&
+ !((base->flag & BASE_SELECTED) /*|| (base == scene->basact)*/)) {
+ /* only selected should be shown */
+ continue;
+ }
+
+ /* check if object belongs to the filtering group if option to filter
+ * objects by the grouped status is on
+ * - used to ease the process of doing multiple-character choreographies
+ */
+ if (ads->filter_grp != NULL) {
+ if (BKE_collection_has_object_recursive(ads->filter_grp, ob) == 0)
+ continue;
+ }
+
+ /* finally, include this object's grease pencil datablock */
+ /* XXX: Should we store these under expanders per item? */
+ items += animdata_filter_gpencil_data(anim_data, ads, ob->data, filter_mode);
+ }
+ }
+ }
+ else {
+ bGPdata *gpd;
+
+ /* Grab all Grease Pencil datablocks directly from main,
+ * but only those that seem to be useful somewhere */
+ for (gpd = ac->bmain->gpencils.first; gpd; gpd = gpd->id.next) {
+ /* only show if gpd is used by something... */
+ if (ID_REAL_USERS(gpd) < 1)
+ continue;
+
+ /* add GP frames from this datablock */
+ items += animdata_filter_gpencil_data(anim_data, ads, gpd, filter_mode);
+ }
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
/* Helper for Grease Pencil data integrated with main DopeSheet */
-static size_t animdata_filter_ds_gpencil(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bGPdata *gpd, int filter_mode)
+static size_t animdata_filter_ds_gpencil(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bGPdata *gpd, int filter_mode)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
-
- /* add relevant animation channels for Grease Pencil */
- BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd))
- {
- /* add animation channels */
- tmp_items += animfilter_block_data(ac, &tmp_data, ads, &gpd->id, filter_mode);
-
- /* add Grease Pencil layers */
- // TODO: do these need a separate expander?
- // XXX: what order should these go in?
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include data-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* check if filtering by active status */
- // XXX: active check here needs checking
- if (ANIMCHANNEL_ACTIVEOK(gpd)) {
- ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_DSGPENCIL, gpd, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- /* return the number of items added to the list */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* add relevant animation channels for Grease Pencil */
+ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_GPD(gpd))
+ {
+ /* add animation channels */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, &gpd->id, filter_mode);
+
+ /* add Grease Pencil layers */
+ // TODO: do these need a separate expander?
+ // XXX: what order should these go in?
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ // XXX: active check here needs checking
+ if (ANIMCHANNEL_ACTIVEOK(gpd)) {
+ ANIMCHANNEL_NEW_CHANNEL(gpd, ANIMTYPE_DSGPENCIL, gpd, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
/* Helper for Cache File data integrated with main DopeSheet */
-static size_t animdata_filter_ds_cachefile(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, CacheFile *cache_file, int filter_mode)
+static size_t animdata_filter_ds_cachefile(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, CacheFile *cache_file, int filter_mode)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
-
- /* add relevant animation channels for Cache File */
- BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_CACHEFILE_OBJD(cache_file))
- {
- /* add animation channels */
- tmp_items += animfilter_block_data(ac, &tmp_data, ads, &cache_file->id, filter_mode);
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include data-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* check if filtering by active status */
- // XXX: active check here needs checking
- if (ANIMCHANNEL_ACTIVEOK(cache_file)) {
- ANIMCHANNEL_NEW_CHANNEL(cache_file, ANIMTYPE_DSCACHEFILE, cache_file, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- /* return the number of items added to the list */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* add relevant animation channels for Cache File */
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_CACHEFILE_OBJD(cache_file))
+ {
+ /* add animation channels */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, &cache_file->id, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ // XXX: active check here needs checking
+ if (ANIMCHANNEL_ACTIVEOK(cache_file)) {
+ ANIMCHANNEL_NEW_CHANNEL(cache_file, ANIMTYPE_DSCACHEFILE, cache_file, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
/* Helper for Mask Editing - mask layers */
static size_t animdata_filter_mask_data(ListBase *anim_data, Mask *mask, const int filter_mode)
{
- MaskLayer *masklay_act = BKE_mask_layer_active(mask);
- MaskLayer *masklay;
- size_t items = 0;
-
- /* loop over layers as the conditions are acceptable */
- for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
- /* only if selected */
- if (ANIMCHANNEL_SELOK(SEL_MASKLAY(masklay)) ) {
- /* only if editable */
- if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_MASK(masklay)) {
- /* active... */
- if (!(filter_mode & ANIMFILTER_ACTIVE) || (masklay_act == masklay)) {
- /* add to list */
- ANIMCHANNEL_NEW_CHANNEL(masklay, ANIMTYPE_MASKLAYER, mask, NULL);
- }
- }
- }
- }
-
- return items;
+ MaskLayer *masklay_act = BKE_mask_layer_active(mask);
+ MaskLayer *masklay;
+ size_t items = 0;
+
+ /* loop over layers as the conditions are acceptable */
+ for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
+ /* only if selected */
+ if (ANIMCHANNEL_SELOK(SEL_MASKLAY(masklay))) {
+ /* only if editable */
+ if (!(filter_mode & ANIMFILTER_FOREDIT) || EDITABLE_MASK(masklay)) {
+ /* active... */
+ if (!(filter_mode & ANIMFILTER_ACTIVE) || (masklay_act == masklay)) {
+ /* add to list */
+ ANIMCHANNEL_NEW_CHANNEL(masklay, ANIMTYPE_MASKLAYER, mask, NULL);
+ }
+ }
+ }
+ }
+
+ return items;
}
/* Grab all mask data */
-static size_t animdata_filter_mask(Main *bmain, ListBase *anim_data, void *UNUSED(data), int filter_mode)
+static size_t animdata_filter_mask(Main *bmain,
+ ListBase *anim_data,
+ void *UNUSED(data),
+ int filter_mode)
{
- Mask *mask;
- size_t items = 0;
-
- /* for now, grab mask datablocks directly from main */
- // XXX: this is not good...
- for (mask = bmain->masks.first; mask; mask = mask->id.next) {
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
-
- /* only show if mask is used by something... */
- if (ID_REAL_USERS(mask) < 1)
- continue;
-
- /* add mask animation channels */
- BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_MASK(mask))
- {
- tmp_items += animdata_filter_mask_data(&tmp_data, mask, filter_mode);
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include data-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* add mask datablock as channel too (if for drawing, and it has layers) */
- ANIMCHANNEL_NEW_CHANNEL(mask, ANIMTYPE_MASKDATABLOCK, NULL, NULL);
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
- }
-
- /* return the number of items added to the list */
- return items;
+ Mask *mask;
+ size_t items = 0;
+
+ /* for now, grab mask datablocks directly from main */
+ // XXX: this is not good...
+ for (mask = bmain->masks.first; mask; mask = mask->id.next) {
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+
+ /* only show if mask is used by something... */
+ if (ID_REAL_USERS(mask) < 1)
+ continue;
+
+ /* add mask animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_MASK(mask))
+ {
+ tmp_items += animdata_filter_mask_data(&tmp_data, mask, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* add mask datablock as channel too (if for drawing, and it has layers) */
+ ANIMCHANNEL_NEW_CHANNEL(mask, ANIMTYPE_MASKDATABLOCK, NULL, NULL);
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
/* NOTE: owner_id is scene, material, or texture block, which is the direct owner of the node tree in question */
-static size_t animdata_filter_ds_nodetree_group(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, bNodeTree *ntree, int filter_mode)
+static size_t animdata_filter_ds_nodetree_group(bAnimContext *ac,
+ ListBase *anim_data,
+ bDopeSheet *ads,
+ ID *owner_id,
+ bNodeTree *ntree,
+ int filter_mode)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
-
- /* add nodetree animation channels */
- BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_NTREE_DATA(ntree))
- {
- /* animation data filtering */
- tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ntree, filter_mode);
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include data-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* check if filtering by active status */
- if (ANIMCHANNEL_ACTIVEOK(ntree)) {
- ANIMCHANNEL_NEW_CHANNEL(ntree, ANIMTYPE_DSNTREE, owner_id, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- /* return the number of items added to the list */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* add nodetree animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_NTREE_DATA(ntree))
+ {
+ /* animation data filtering */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ntree, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ if (ANIMCHANNEL_ACTIVEOK(ntree)) {
+ ANIMCHANNEL_NEW_CHANNEL(ntree, ANIMTYPE_DSNTREE, owner_id, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
-static size_t animdata_filter_ds_nodetree(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, bNodeTree *ntree, int filter_mode)
+static size_t animdata_filter_ds_nodetree(bAnimContext *ac,
+ ListBase *anim_data,
+ bDopeSheet *ads,
+ ID *owner_id,
+ bNodeTree *ntree,
+ int filter_mode)
{
- bNode *node;
- size_t items = 0;
-
- items += animdata_filter_ds_nodetree_group(ac, anim_data, ads, owner_id, ntree, filter_mode);
-
- for (node = ntree->nodes.first; node; node = node->next) {
- if (node->type == NODE_GROUP) {
- if (node->id) {
- if ((ads->filterflag & ADS_FILTER_ONLYSEL) && (node->flag & NODE_SELECT) == 0) {
- continue;
- }
- /* Recurse into the node group */
- items += animdata_filter_ds_nodetree(ac, anim_data, ads, owner_id, (bNodeTree *) node->id,
- filter_mode | ANIMFILTER_TMP_IGNORE_ONLYSEL);
- }
- }
- }
-
- return items;
+ bNode *node;
+ size_t items = 0;
+
+ items += animdata_filter_ds_nodetree_group(ac, anim_data, ads, owner_id, ntree, filter_mode);
+
+ for (node = ntree->nodes.first; node; node = node->next) {
+ if (node->type == NODE_GROUP) {
+ if (node->id) {
+ if ((ads->filterflag & ADS_FILTER_ONLYSEL) && (node->flag & NODE_SELECT) == 0) {
+ continue;
+ }
+ /* Recurse into the node group */
+ items += animdata_filter_ds_nodetree(ac,
+ anim_data,
+ ads,
+ owner_id,
+ (bNodeTree *)node->id,
+ filter_mode | ANIMFILTER_TMP_IGNORE_ONLYSEL);
+ }
+ }
+ }
+
+ return items;
}
-static size_t animdata_filter_ds_linestyle(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
+static size_t animdata_filter_ds_linestyle(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
{
- ViewLayer *view_layer;
- FreestyleLineSet *lineset;
- size_t items = 0;
-
- for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
- for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) {
- if (lineset->linestyle) {
- lineset->linestyle->id.tag |= LIB_TAG_DOIT;
- }
- }
- }
-
- for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
- /* skip render layers without Freestyle enabled */
- if ((view_layer->flag & VIEW_LAYER_FREESTYLE) == 0) {
- continue;
- }
-
- /* loop over linesets defined in the render layer */
- for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) {
- FreestyleLineStyle *linestyle = lineset->linestyle;
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
-
- if ((linestyle == NULL) ||
- !(linestyle->id.tag & LIB_TAG_DOIT))
- {
- continue;
- }
- linestyle->id.tag &= ~LIB_TAG_DOIT;
-
- /* add scene-level animation channels */
- BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_LS_SCED(linestyle))
- {
- /* animation data filtering */
- tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)linestyle, filter_mode);
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include anim-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* check if filtering by active status */
- if (ANIMCHANNEL_ACTIVEOK(linestyle)) {
- ANIMCHANNEL_NEW_CHANNEL(linestyle, ANIMTYPE_DSLINESTYLE, sce, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
- }
- }
-
- /* return the number of items added to the list */
- return items;
+ ViewLayer *view_layer;
+ FreestyleLineSet *lineset;
+ size_t items = 0;
+
+ for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
+ for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) {
+ if (lineset->linestyle) {
+ lineset->linestyle->id.tag |= LIB_TAG_DOIT;
+ }
+ }
+ }
+
+ for (view_layer = sce->view_layers.first; view_layer; view_layer = view_layer->next) {
+ /* skip render layers without Freestyle enabled */
+ if ((view_layer->flag & VIEW_LAYER_FREESTYLE) == 0) {
+ continue;
+ }
+
+ /* loop over linesets defined in the render layer */
+ for (lineset = view_layer->freestyle_config.linesets.first; lineset; lineset = lineset->next) {
+ FreestyleLineStyle *linestyle = lineset->linestyle;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+
+ if ((linestyle == NULL) || !(linestyle->id.tag & LIB_TAG_DOIT)) {
+ continue;
+ }
+ linestyle->id.tag &= ~LIB_TAG_DOIT;
+
+ /* add scene-level animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_LS_SCED(linestyle))
+ {
+ /* animation data filtering */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)linestyle, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include anim-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ if (ANIMCHANNEL_ACTIVEOK(linestyle)) {
+ ANIMCHANNEL_NEW_CHANNEL(linestyle, ANIMTYPE_DSLINESTYLE, sce, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+ }
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
-static size_t animdata_filter_ds_texture(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads,
- Tex *tex, ID *owner_id, int filter_mode)
+static size_t animdata_filter_ds_texture(bAnimContext *ac,
+ ListBase *anim_data,
+ bDopeSheet *ads,
+ Tex *tex,
+ ID *owner_id,
+ int filter_mode)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
-
- /* add texture's animation data to temp collection */
- BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_TEX_DATA(tex))
- {
- /* texture animdata */
- tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)tex, filter_mode);
-
- /* nodes */
- if ((tex->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
- /* owner_id as id instead of texture, since it'll otherwise be impossible to track the depth */
- // FIXME: perhaps as a result, textures should NOT be included under materials, but under their own section instead
- // so that free-floating textures can also be animated
- tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)tex, tex->nodetree, filter_mode);
- }
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include texture-expand widget? */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* check if filtering by active status */
- if (ANIMCHANNEL_ACTIVEOK(tex)) {
- ANIMCHANNEL_NEW_CHANNEL(tex, ANIMTYPE_DSTEX, owner_id, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- /* return the number of items added to the list */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* add texture's animation data to temp collection */
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_TEX_DATA(tex))
+ {
+ /* texture animdata */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)tex, filter_mode);
+
+ /* nodes */
+ if ((tex->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
+ /* owner_id as id instead of texture, since it'll otherwise be impossible to track the depth */
+ // FIXME: perhaps as a result, textures should NOT be included under materials, but under their own section instead
+ // so that free-floating textures can also be animated
+ tmp_items += animdata_filter_ds_nodetree(
+ ac, &tmp_data, ads, (ID *)tex, tex->nodetree, filter_mode);
+ }
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include texture-expand widget? */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ if (ANIMCHANNEL_ACTIVEOK(tex)) {
+ ANIMCHANNEL_NEW_CHANNEL(tex, ANIMTYPE_DSTEX, owner_id, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
/* NOTE: owner_id is the direct owner of the texture stack in question
* It used to be Material/Light/World before the Blender Internal removal for 2.8
*/
-static size_t animdata_filter_ds_textures(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, int filter_mode)
+static size_t animdata_filter_ds_textures(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, ID *owner_id, int filter_mode)
{
- MTex **mtex = NULL;
- size_t items = 0;
- int a = 0;
-
- /* get datatype specific data first */
- if (owner_id == NULL)
- return 0;
-
- switch (GS(owner_id->name)) {
- case ID_PA:
- {
- ParticleSettings *part = (ParticleSettings *)owner_id;
- mtex = (MTex **)(&part->mtex);
- break;
- }
- default:
- {
- /* invalid/unsupported option */
- if (G.debug & G_DEBUG)
- printf("ERROR: Unsupported owner_id (i.e. texture stack) for filter textures - %s\n", owner_id->name);
- return 0;
- }
- }
-
- /* firstly check that we actuallly have some textures, by gathering all textures in a temp list */
- for (a = 0; a < MAX_MTEX; a++) {
- Tex *tex = (mtex[a]) ? mtex[a]->tex : NULL;
-
- /* for now, if no texture returned, skip (this shouldn't confuse the user I hope) */
- if (tex == NULL)
- continue;
-
- /* add texture's anim channels */
- items += animdata_filter_ds_texture(ac, anim_data, ads, tex, owner_id, filter_mode);
- }
-
- /* return the number of items added to the list */
- return items;
+ MTex **mtex = NULL;
+ size_t items = 0;
+ int a = 0;
+
+ /* get datatype specific data first */
+ if (owner_id == NULL)
+ return 0;
+
+ switch (GS(owner_id->name)) {
+ case ID_PA: {
+ ParticleSettings *part = (ParticleSettings *)owner_id;
+ mtex = (MTex **)(&part->mtex);
+ break;
+ }
+ default: {
+ /* invalid/unsupported option */
+ if (G.debug & G_DEBUG)
+ printf("ERROR: Unsupported owner_id (i.e. texture stack) for filter textures - %s\n",
+ owner_id->name);
+ return 0;
+ }
+ }
+
+ /* firstly check that we actuallly have some textures, by gathering all textures in a temp list */
+ for (a = 0; a < MAX_MTEX; a++) {
+ Tex *tex = (mtex[a]) ? mtex[a]->tex : NULL;
+
+ /* for now, if no texture returned, skip (this shouldn't confuse the user I hope) */
+ if (tex == NULL)
+ continue;
+
+ /* add texture's anim channels */
+ items += animdata_filter_ds_texture(ac, anim_data, ads, tex, owner_id, filter_mode);
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
-
-static size_t animdata_filter_ds_material(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Material *ma, int filter_mode)
+static size_t animdata_filter_ds_material(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Material *ma, int filter_mode)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
-
- /* add material's animation data to temp collection */
- BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_MAT_OBJD(ma))
- {
- /* material's animation data */
- tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ma, filter_mode);
-
- /* nodes */
- if ((ma->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE))
- tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)ma, ma->nodetree, filter_mode);
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include material-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* check if filtering by active status */
- if (ANIMCHANNEL_ACTIVEOK(ma)) {
- ANIMCHANNEL_NEW_CHANNEL(ma, ANIMTYPE_DSMAT, ma, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* add material's animation data to temp collection */
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_MAT_OBJD(ma))
+ {
+ /* material's animation data */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ma, filter_mode);
+
+ /* nodes */
+ if ((ma->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE))
+ tmp_items += animdata_filter_ds_nodetree(
+ ac, &tmp_data, ads, (ID *)ma, ma->nodetree, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include material-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ if (ANIMCHANNEL_ACTIVEOK(ma)) {
+ ANIMCHANNEL_NEW_CHANNEL(ma, ANIMTYPE_DSMAT, ma, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ return items;
}
-static size_t animdata_filter_ds_materials(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
+static size_t animdata_filter_ds_materials(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
{
- bool has_nested = false;
- size_t items = 0;
- int a = 0;
-
- /* first pass: take the materials referenced via the Material slots of the object */
- for (a = 1; a <= ob->totcol; a++) {
- Material *ma = give_current_material(ob, a);
-
- /* if material is valid, try to add relevant contents from here */
- if (ma) {
- /* add channels */
- items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
-
- /* for optimising second pass - check if there's a nested material here to come back for */
- if (has_nested == false) {
- has_nested = (give_node_material(ma) != NULL);
- }
- }
- }
-
- /* second pass: go through a second time looking for "nested" materials (material.material references)
- *
- * NOTE: here we ignore the expanded status of the parent, as it could be too confusing as to why these are
- * disappearing/not available, since the relationships between these is not that clear
- */
- if (has_nested) {
- for (a = 1; a <= ob->totcol; a++) {
- Material *base = give_current_material(ob, a);
- Material *ma = give_node_material(base);
-
- /* add channels from the nested material if it exists
- * - skip if the same material is referenced in its node tree
- * (which is common for BI materials) as that results in
- * confusing duplicates
- */
- if ((ma) && (ma != base)) {
- items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
- }
- }
- }
-
- /* return the number of items added to the list */
- return items;
+ bool has_nested = false;
+ size_t items = 0;
+ int a = 0;
+
+ /* first pass: take the materials referenced via the Material slots of the object */
+ for (a = 1; a <= ob->totcol; a++) {
+ Material *ma = give_current_material(ob, a);
+
+ /* if material is valid, try to add relevant contents from here */
+ if (ma) {
+ /* add channels */
+ items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
+
+ /* for optimising second pass - check if there's a nested material here to come back for */
+ if (has_nested == false) {
+ has_nested = (give_node_material(ma) != NULL);
+ }
+ }
+ }
+
+ /* second pass: go through a second time looking for "nested" materials (material.material references)
+ *
+ * NOTE: here we ignore the expanded status of the parent, as it could be too confusing as to why these are
+ * disappearing/not available, since the relationships between these is not that clear
+ */
+ if (has_nested) {
+ for (a = 1; a <= ob->totcol; a++) {
+ Material *base = give_current_material(ob, a);
+ Material *ma = give_node_material(base);
+
+ /* add channels from the nested material if it exists
+ * - skip if the same material is referenced in its node tree
+ * (which is common for BI materials) as that results in
+ * confusing duplicates
+ */
+ if ((ma) && (ma != base)) {
+ items += animdata_filter_ds_material(ac, anim_data, ads, ma, filter_mode);
+ }
+ }
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
-
/* ............ */
/* Temporary context for modifier linked-data channel extraction */
typedef struct tAnimFilterModifiersContext {
- bAnimContext *ac; /* anim editor context */
- bDopeSheet *ads; /* dopesheet filtering settings */
+ bAnimContext *ac; /* anim editor context */
+ bDopeSheet *ads; /* dopesheet filtering settings */
- ListBase tmp_data; /* list of channels created (but not yet added to the main list) */
- size_t items; /* number of channels created */
+ ListBase tmp_data; /* list of channels created (but not yet added to the main list) */
+ size_t items; /* number of channels created */
- int filter_mode; /* flags for stuff we want to filter */
+ int filter_mode; /* flags for stuff we want to filter */
} tAnimFilterModifiersContext;
-
/* dependency walker callback for modifier dependencies */
-static void animfilter_modifier_idpoin_cb(void *afm_ptr, Object *ob, ID **idpoin, int UNUSED(cb_flag))
+static void animfilter_modifier_idpoin_cb(void *afm_ptr,
+ Object *ob,
+ ID **idpoin,
+ int UNUSED(cb_flag))
{
- tAnimFilterModifiersContext *afm = (tAnimFilterModifiersContext *)afm_ptr;
- ID *owner_id = &ob->id;
- ID *id = *idpoin;
-
- /* NOTE: the walker only guarantees to give us all the ID-ptr *slots*,
- * not just the ones which are actually used, so be careful!
- */
- if (id == NULL)
- return;
-
- /* check if this is something we're interested in... */
- switch (GS(id->name)) {
- case ID_TE: /* Textures */
- {
- Tex *tex = (Tex *)id;
- if (!(afm->ads->filterflag & ADS_FILTER_NOTEX)) {
- afm->items += animdata_filter_ds_texture(afm->ac, &afm->tmp_data, afm->ads, tex, owner_id, afm->filter_mode);
- }
- break;
- }
-
- /* TODO: images? */
- default:
- break;
- }
+ tAnimFilterModifiersContext *afm = (tAnimFilterModifiersContext *)afm_ptr;
+ ID *owner_id = &ob->id;
+ ID *id = *idpoin;
+
+ /* NOTE: the walker only guarantees to give us all the ID-ptr *slots*,
+ * not just the ones which are actually used, so be careful!
+ */
+ if (id == NULL)
+ return;
+
+ /* check if this is something we're interested in... */
+ switch (GS(id->name)) {
+ case ID_TE: /* Textures */
+ {
+ Tex *tex = (Tex *)id;
+ if (!(afm->ads->filterflag & ADS_FILTER_NOTEX)) {
+ afm->items += animdata_filter_ds_texture(
+ afm->ac, &afm->tmp_data, afm->ads, tex, owner_id, afm->filter_mode);
+ }
+ break;
+ }
+
+ /* TODO: images? */
+ default:
+ break;
+ }
}
/* animation linked to data used by modifiers
@@ -2266,861 +2324,886 @@ static void animfilter_modifier_idpoin_cb(void *afm_ptr, Object *ob, ID **idpoin
* attached to any other objects/materials/etc. in the scene
*/
// TODO: do we want an expander for this?
-static size_t animdata_filter_ds_modifiers(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
+static size_t animdata_filter_ds_modifiers(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
{
- tAnimFilterModifiersContext afm = {NULL};
- size_t items = 0;
-
- /* 1) create a temporary "context" containing all the info we have here to pass to the callback
- * use to walk through the dependencies of the modifiers
- *
- * ! Assumes that all other unspecified values (i.e. accumulation buffers) are zero'd out properly
- */
- afm.ac = ac;
- afm.ads = ads;
- afm.filter_mode = filter_mode;
-
- /* 2) walk over dependencies */
- modifiers_foreachIDLink(ob, animfilter_modifier_idpoin_cb, &afm);
-
- /* 3) extract data from the context, merging it back into the standard list */
- if (afm.items) {
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &afm.tmp_data);
- BLI_assert(BLI_listbase_is_empty(&afm.tmp_data));
- items += afm.items;
- }
-
- return items;
+ tAnimFilterModifiersContext afm = {NULL};
+ size_t items = 0;
+
+ /* 1) create a temporary "context" containing all the info we have here to pass to the callback
+ * use to walk through the dependencies of the modifiers
+ *
+ * ! Assumes that all other unspecified values (i.e. accumulation buffers) are zero'd out properly
+ */
+ afm.ac = ac;
+ afm.ads = ads;
+ afm.filter_mode = filter_mode;
+
+ /* 2) walk over dependencies */
+ modifiers_foreachIDLink(ob, animfilter_modifier_idpoin_cb, &afm);
+
+ /* 3) extract data from the context, merging it back into the standard list */
+ if (afm.items) {
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &afm.tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&afm.tmp_data));
+ items += afm.items;
+ }
+
+ return items;
}
/* ............ */
-
-static size_t animdata_filter_ds_particles(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
+static size_t animdata_filter_ds_particles(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
{
- ParticleSystem *psys;
- size_t items = 0;
-
- for (psys = ob->particlesystem.first; psys; psys = psys->next) {
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
-
- /* if no material returned, skip - so that we don't get weird blank entries... */
- if (ELEM(NULL, psys->part, psys->part->adt))
- continue;
-
- /* add particle-system's animation data to temp collection */
- BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_PART_OBJD(psys->part))
- {
- /* particle system's animation data */
- tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)psys->part, filter_mode);
-
- /* textures */
- if (!(ads->filterflag & ADS_FILTER_NOTEX))
- tmp_items += animdata_filter_ds_textures(ac, &tmp_data, ads, (ID *)psys->part, filter_mode);
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include particle-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* check if filtering by active status */
- if (ANIMCHANNEL_ACTIVEOK(psys->part)) {
- ANIMCHANNEL_NEW_CHANNEL(psys->part, ANIMTYPE_DSPART, psys->part, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
- }
-
- /* return the number of items added to the list */
- return items;
+ ParticleSystem *psys;
+ size_t items = 0;
+
+ for (psys = ob->particlesystem.first; psys; psys = psys->next) {
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+
+ /* if no material returned, skip - so that we don't get weird blank entries... */
+ if (ELEM(NULL, psys->part, psys->part->adt))
+ continue;
+
+ /* add particle-system's animation data to temp collection */
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_PART_OBJD(psys->part))
+ {
+ /* particle system's animation data */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)psys->part, filter_mode);
+
+ /* textures */
+ if (!(ads->filterflag & ADS_FILTER_NOTEX))
+ tmp_items += animdata_filter_ds_textures(
+ ac, &tmp_data, ads, (ID *)psys->part, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include particle-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ if (ANIMCHANNEL_ACTIVEOK(psys->part)) {
+ ANIMCHANNEL_NEW_CHANNEL(psys->part, ANIMTYPE_DSPART, psys->part, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
-
-static size_t animdata_filter_ds_obdata(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
+static size_t animdata_filter_ds_obdata(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
-
- IdAdtTemplate *iat = ob->data;
- short type = 0, expanded = 0;
-
- /* get settings based on data type */
- switch (ob->type) {
- case OB_CAMERA: /* ------- Camera ------------ */
- {
- Camera *ca = (Camera *)ob->data;
-
- if (ads->filterflag & ADS_FILTER_NOCAM)
- return 0;
-
- type = ANIMTYPE_DSCAM;
- expanded = FILTER_CAM_OBJD(ca);
- break;
- }
- case OB_LAMP: /* ---------- Light ----------- */
- {
- Light *la = (Light *)ob->data;
-
- if (ads->filterflag & ADS_FILTER_NOLAM)
- return 0;
-
- type = ANIMTYPE_DSLAM;
- expanded = FILTER_LAM_OBJD(la);
- break;
- }
- case OB_CURVE: /* ------- Curve ---------- */
- case OB_SURF: /* ------- Nurbs Surface ---------- */
- case OB_FONT: /* ------- Text Curve ---------- */
- {
- Curve *cu = (Curve *)ob->data;
-
- if (ads->filterflag & ADS_FILTER_NOCUR)
- return 0;
-
- type = ANIMTYPE_DSCUR;
- expanded = FILTER_CUR_OBJD(cu);
- break;
- }
- case OB_MBALL: /* ------- MetaBall ---------- */
- {
- MetaBall *mb = (MetaBall *)ob->data;
-
- if (ads->filterflag & ADS_FILTER_NOMBA)
- return 0;
-
- type = ANIMTYPE_DSMBALL;
- expanded = FILTER_MBALL_OBJD(mb);
- break;
- }
- case OB_ARMATURE: /* ------- Armature ---------- */
- {
- bArmature *arm = (bArmature *)ob->data;
-
- if (ads->filterflag & ADS_FILTER_NOARM)
- return 0;
-
- type = ANIMTYPE_DSARM;
- expanded = FILTER_ARM_OBJD(arm);
- break;
- }
- case OB_MESH: /* ------- Mesh ---------- */
- {
- Mesh *me = (Mesh *)ob->data;
-
- if (ads->filterflag & ADS_FILTER_NOMESH)
- return 0;
-
- type = ANIMTYPE_DSMESH;
- expanded = FILTER_MESH_OBJD(me);
- break;
- }
- case OB_LATTICE: /* ---- Lattice ---- */
- {
- Lattice *lt = (Lattice *)ob->data;
-
- if (ads->filterflag & ADS_FILTER_NOLAT)
- return 0;
-
- type = ANIMTYPE_DSLAT;
- expanded = FILTER_LATTICE_OBJD(lt);
- break;
- }
- case OB_SPEAKER: /* ---------- Speaker ----------- */
- {
- Speaker *spk = (Speaker *)ob->data;
-
- type = ANIMTYPE_DSSPK;
- expanded = FILTER_SPK_OBJD(spk);
- break;
- }
- }
-
- /* add object data animation channels */
- BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
- {
- /* animation data filtering */
- tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)iat, filter_mode);
-
- /* sub-data filtering... */
- switch (ob->type) {
- case OB_LAMP: /* light - textures + nodetree */
- {
- Light *la = ob->data;
- bNodeTree *ntree = la->nodetree;
-
- /* nodetree */
- if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE))
- tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, &la->id, ntree, filter_mode);
- break;
- }
- }
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include data-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* check if filtering by active status */
- if (ANIMCHANNEL_ACTIVEOK(iat)) {
- ANIMCHANNEL_NEW_CHANNEL(iat, type, iat, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- /* return the number of items added to the list */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ IdAdtTemplate *iat = ob->data;
+ short type = 0, expanded = 0;
+
+ /* get settings based on data type */
+ switch (ob->type) {
+ case OB_CAMERA: /* ------- Camera ------------ */
+ {
+ Camera *ca = (Camera *)ob->data;
+
+ if (ads->filterflag & ADS_FILTER_NOCAM)
+ return 0;
+
+ type = ANIMTYPE_DSCAM;
+ expanded = FILTER_CAM_OBJD(ca);
+ break;
+ }
+ case OB_LAMP: /* ---------- Light ----------- */
+ {
+ Light *la = (Light *)ob->data;
+
+ if (ads->filterflag & ADS_FILTER_NOLAM)
+ return 0;
+
+ type = ANIMTYPE_DSLAM;
+ expanded = FILTER_LAM_OBJD(la);
+ break;
+ }
+ case OB_CURVE: /* ------- Curve ---------- */
+ case OB_SURF: /* ------- Nurbs Surface ---------- */
+ case OB_FONT: /* ------- Text Curve ---------- */
+ {
+ Curve *cu = (Curve *)ob->data;
+
+ if (ads->filterflag & ADS_FILTER_NOCUR)
+ return 0;
+
+ type = ANIMTYPE_DSCUR;
+ expanded = FILTER_CUR_OBJD(cu);
+ break;
+ }
+ case OB_MBALL: /* ------- MetaBall ---------- */
+ {
+ MetaBall *mb = (MetaBall *)ob->data;
+
+ if (ads->filterflag & ADS_FILTER_NOMBA)
+ return 0;
+
+ type = ANIMTYPE_DSMBALL;
+ expanded = FILTER_MBALL_OBJD(mb);
+ break;
+ }
+ case OB_ARMATURE: /* ------- Armature ---------- */
+ {
+ bArmature *arm = (bArmature *)ob->data;
+
+ if (ads->filterflag & ADS_FILTER_NOARM)
+ return 0;
+
+ type = ANIMTYPE_DSARM;
+ expanded = FILTER_ARM_OBJD(arm);
+ break;
+ }
+ case OB_MESH: /* ------- Mesh ---------- */
+ {
+ Mesh *me = (Mesh *)ob->data;
+
+ if (ads->filterflag & ADS_FILTER_NOMESH)
+ return 0;
+
+ type = ANIMTYPE_DSMESH;
+ expanded = FILTER_MESH_OBJD(me);
+ break;
+ }
+ case OB_LATTICE: /* ---- Lattice ---- */
+ {
+ Lattice *lt = (Lattice *)ob->data;
+
+ if (ads->filterflag & ADS_FILTER_NOLAT)
+ return 0;
+
+ type = ANIMTYPE_DSLAT;
+ expanded = FILTER_LATTICE_OBJD(lt);
+ break;
+ }
+ case OB_SPEAKER: /* ---------- Speaker ----------- */
+ {
+ Speaker *spk = (Speaker *)ob->data;
+
+ type = ANIMTYPE_DSSPK;
+ expanded = FILTER_SPK_OBJD(spk);
+ break;
+ }
+ }
+
+ /* add object data animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
+ {
+ /* animation data filtering */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)iat, filter_mode);
+
+ /* sub-data filtering... */
+ switch (ob->type) {
+ case OB_LAMP: /* light - textures + nodetree */
+ {
+ Light *la = ob->data;
+ bNodeTree *ntree = la->nodetree;
+
+ /* nodetree */
+ if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE))
+ tmp_items += animdata_filter_ds_nodetree(
+ ac, &tmp_data, ads, &la->id, ntree, filter_mode);
+ break;
+ }
+ }
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ if (ANIMCHANNEL_ACTIVEOK(iat)) {
+ ANIMCHANNEL_NEW_CHANNEL(iat, type, iat, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
/* shapekey-level animation */
-static size_t animdata_filter_ds_keyanim(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, Key *key, int filter_mode)
+static size_t animdata_filter_ds_keyanim(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, Key *key, int filter_mode)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
-
- /* add shapekey-level animation channels */
- BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_SKE_OBJD(key))
- {
- /* animation data filtering */
- tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)key, filter_mode);
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include key-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- if (ANIMCHANNEL_ACTIVEOK(key)) {
- ANIMCHANNEL_NEW_CHANNEL(key, ANIMTYPE_DSSKEY, ob, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- /* return the number of items added to the list */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* add shapekey-level animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_SKE_OBJD(key))
+ {
+ /* animation data filtering */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)key, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include key-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ if (ANIMCHANNEL_ACTIVEOK(key)) {
+ ANIMCHANNEL_NEW_CHANNEL(key, ANIMTYPE_DSSKEY, ob, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
-
/* object-level animation */
-static size_t animdata_filter_ds_obanim(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
+static size_t animdata_filter_ds_obanim(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Object *ob, int filter_mode)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
-
- AnimData *adt = ob->adt;
- short type = 0, expanded = 1;
- void *cdata = NULL;
-
- /* determine the type of expander channels to use */
- /* this is the best way to do this for now... */
- ANIMDATA_FILTER_CASES(
- ob,
- { /* AnimData - no channel, but consider data */ },
- { /* NLA - no channel, but consider data */ },
- { /* Drivers */
- type = ANIMTYPE_FILLDRIVERS;
- cdata = adt;
- expanded = EXPANDED_DRVD(adt);
- },
- { /* NLA Strip Controls - no dedicated channel for now (XXX) */ },
- { /* Keyframes */
- type = ANIMTYPE_FILLACTD;
- cdata = adt->action;
- expanded = EXPANDED_ACTC(adt->action);
- });
-
- /* add object-level animation channels */
- BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
- {
- /* animation data filtering */
- tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ob, filter_mode);
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include anim-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- if (type != ANIMTYPE_NONE) {
- /* NOTE: active-status (and the associated checks) don't apply here... */
- ANIMCHANNEL_NEW_CHANNEL(cdata, type, ob, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- /* return the number of items added to the list */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ AnimData *adt = ob->adt;
+ short type = 0, expanded = 1;
+ void *cdata = NULL;
+
+ /* determine the type of expander channels to use */
+ /* this is the best way to do this for now... */
+ ANIMDATA_FILTER_CASES(
+ ob,
+ {/* AnimData - no channel, but consider data */},
+ {/* NLA - no channel, but consider data */},
+ { /* Drivers */
+ type = ANIMTYPE_FILLDRIVERS;
+ cdata = adt;
+ expanded = EXPANDED_DRVD(adt);
+ },
+ {/* NLA Strip Controls - no dedicated channel for now (XXX) */},
+ { /* Keyframes */
+ type = ANIMTYPE_FILLACTD;
+ cdata = adt->action;
+ expanded = EXPANDED_ACTC(adt->action);
+ });
+
+ /* add object-level animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
+ {
+ /* animation data filtering */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)ob, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include anim-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ if (type != ANIMTYPE_NONE) {
+ /* NOTE: active-status (and the associated checks) don't apply here... */
+ ANIMCHANNEL_NEW_CHANNEL(cdata, type, ob, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
/* get animation channels from object2 */
-static size_t animdata_filter_dopesheet_ob(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
+static size_t animdata_filter_dopesheet_ob(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Base *base, int filter_mode)
{
- ListBase tmp_data = {NULL, NULL};
- Object *ob = base->object;
- size_t tmp_items = 0;
- size_t items = 0;
-
- /* filter data contained under object first */
- BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_OBJC(ob))
- {
- Key *key = BKE_key_from_object(ob);
-
- /* object-level animation */
- if ((ob->adt) && !(ads->filterflag & ADS_FILTER_NOOBJ)) {
- tmp_items += animdata_filter_ds_obanim(ac, &tmp_data, ads, ob, filter_mode);
- }
-
- /* shape-key */
- if ((key && key->adt) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
- tmp_items += animdata_filter_ds_keyanim(ac, &tmp_data, ads, ob, key, filter_mode);
- }
-
- /* modifiers */
- if ((ob->modifiers.first) && !(ads->filterflag & ADS_FILTER_NOMODIFIERS)) {
- tmp_items += animdata_filter_ds_modifiers(ac, &tmp_data, ads, ob, filter_mode);
- }
-
- /* materials */
- if ((ob->totcol) && !(ads->filterflag & ADS_FILTER_NOMAT)) {
- tmp_items += animdata_filter_ds_materials(ac, &tmp_data, ads, ob, filter_mode);
- }
-
- /* object data */
- if (ob->data) {
- tmp_items += animdata_filter_ds_obdata(ac, &tmp_data, ads, ob, filter_mode);
- }
-
- /* particles */
- if ((ob->particlesystem.first) && !(ads->filterflag & ADS_FILTER_NOPART)) {
- tmp_items += animdata_filter_ds_particles(ac, &tmp_data, ads, ob, filter_mode);
- }
-
- /* grease pencil */
- if ((ob->type == OB_GPENCIL) &&
- (ob->data) && !(ads->filterflag & ADS_FILTER_NOGPENCIL))
- {
- tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, ob->data, filter_mode);
- }
- }
- END_ANIMFILTER_SUBCHANNELS;
-
-
- /* if we collected some channels, add these to the new list... */
- if (tmp_items) {
- /* firstly add object expander if required */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* check if filtering by selection */
- // XXX: double-check on this - most of the time, a lot of tools need to filter out these channels!
- if (ANIMCHANNEL_SELOK((base->flag & BASE_SELECTED))) {
- /* check if filtering by active status */
- if (ANIMCHANNEL_ACTIVEOK(ob)) {
- ANIMCHANNEL_NEW_CHANNEL(base, ANIMTYPE_OBJECT, ob, NULL);
- }
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- /* return the number of items added */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ Object *ob = base->object;
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* filter data contained under object first */
+ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_OBJC(ob))
+ {
+ Key *key = BKE_key_from_object(ob);
+
+ /* object-level animation */
+ if ((ob->adt) && !(ads->filterflag & ADS_FILTER_NOOBJ)) {
+ tmp_items += animdata_filter_ds_obanim(ac, &tmp_data, ads, ob, filter_mode);
+ }
+
+ /* shape-key */
+ if ((key && key->adt) && !(ads->filterflag & ADS_FILTER_NOSHAPEKEYS)) {
+ tmp_items += animdata_filter_ds_keyanim(ac, &tmp_data, ads, ob, key, filter_mode);
+ }
+
+ /* modifiers */
+ if ((ob->modifiers.first) && !(ads->filterflag & ADS_FILTER_NOMODIFIERS)) {
+ tmp_items += animdata_filter_ds_modifiers(ac, &tmp_data, ads, ob, filter_mode);
+ }
+
+ /* materials */
+ if ((ob->totcol) && !(ads->filterflag & ADS_FILTER_NOMAT)) {
+ tmp_items += animdata_filter_ds_materials(ac, &tmp_data, ads, ob, filter_mode);
+ }
+
+ /* object data */
+ if (ob->data) {
+ tmp_items += animdata_filter_ds_obdata(ac, &tmp_data, ads, ob, filter_mode);
+ }
+
+ /* particles */
+ if ((ob->particlesystem.first) && !(ads->filterflag & ADS_FILTER_NOPART)) {
+ tmp_items += animdata_filter_ds_particles(ac, &tmp_data, ads, ob, filter_mode);
+ }
+
+ /* grease pencil */
+ if ((ob->type == OB_GPENCIL) && (ob->data) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) {
+ tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, ob->data, filter_mode);
+ }
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* if we collected some channels, add these to the new list... */
+ if (tmp_items) {
+ /* firstly add object expander if required */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by selection */
+ // XXX: double-check on this - most of the time, a lot of tools need to filter out these channels!
+ if (ANIMCHANNEL_SELOK((base->flag & BASE_SELECTED))) {
+ /* check if filtering by active status */
+ if (ANIMCHANNEL_ACTIVEOK(ob)) {
+ ANIMCHANNEL_NEW_CHANNEL(base, ANIMTYPE_OBJECT, ob, NULL);
+ }
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ /* return the number of items added */
+ return items;
}
-static size_t animdata_filter_ds_world(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, World *wo, int filter_mode)
+static size_t animdata_filter_ds_world(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, World *wo, int filter_mode)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
-
- /* add world animation channels */
- BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_WOR_SCED(wo))
- {
- /* animation data filtering */
- tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)wo, filter_mode);
-
- /* nodes */
- if ((wo->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE))
- tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)wo, wo->nodetree, filter_mode);
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include data-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* check if filtering by active status */
- if (ANIMCHANNEL_ACTIVEOK(wo)) {
- ANIMCHANNEL_NEW_CHANNEL(wo, ANIMTYPE_DSWOR, sce, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- /* return the number of items added to the list */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* add world animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(FILTER_WOR_SCED(wo))
+ {
+ /* animation data filtering */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)wo, filter_mode);
+
+ /* nodes */
+ if ((wo->nodetree) && !(ads->filterflag & ADS_FILTER_NONTREE))
+ tmp_items += animdata_filter_ds_nodetree(
+ ac, &tmp_data, ads, (ID *)wo, wo->nodetree, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ if (ANIMCHANNEL_ACTIVEOK(wo)) {
+ ANIMCHANNEL_NEW_CHANNEL(wo, ANIMTYPE_DSWOR, sce, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
-static size_t animdata_filter_ds_scene(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
+static size_t animdata_filter_ds_scene(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
-
- AnimData *adt = sce->adt;
- short type = 0, expanded = 1;
- void *cdata = NULL;
-
- /* determine the type of expander channels to use */
- // this is the best way to do this for now...
- ANIMDATA_FILTER_CASES(
- sce,
- { /* AnimData - no channel, but consider data */},
- { /* NLA - no channel, but consider data */},
- { /* Drivers */
- type = ANIMTYPE_FILLDRIVERS;
- cdata = adt;
- expanded = EXPANDED_DRVD(adt);
- },
- { /* NLA Strip Controls - no dedicated channel for now (XXX) */ },
- { /* Keyframes */
- type = ANIMTYPE_FILLACTD;
- cdata = adt->action;
- expanded = EXPANDED_ACTC(adt->action);
- });
-
- /* add scene-level animation channels */
- BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
- {
- /* animation data filtering */
- tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)sce, filter_mode);
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* did we find anything? */
- if (tmp_items) {
- /* include anim-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- if (type != ANIMTYPE_NONE) {
- /* NOTE: active-status (and the associated checks) don't apply here... */
- ANIMCHANNEL_NEW_CHANNEL(cdata, type, sce, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- /* return the number of items added to the list */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ AnimData *adt = sce->adt;
+ short type = 0, expanded = 1;
+ void *cdata = NULL;
+
+ /* determine the type of expander channels to use */
+ // this is the best way to do this for now...
+ ANIMDATA_FILTER_CASES(
+ sce,
+ {/* AnimData - no channel, but consider data */},
+ {/* NLA - no channel, but consider data */},
+ { /* Drivers */
+ type = ANIMTYPE_FILLDRIVERS;
+ cdata = adt;
+ expanded = EXPANDED_DRVD(adt);
+ },
+ {/* NLA Strip Controls - no dedicated channel for now (XXX) */},
+ { /* Keyframes */
+ type = ANIMTYPE_FILLACTD;
+ cdata = adt->action;
+ expanded = EXPANDED_ACTC(adt->action);
+ });
+
+ /* add scene-level animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(expanded)
+ {
+ /* animation data filtering */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)sce, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include anim-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ if (type != ANIMTYPE_NONE) {
+ /* NOTE: active-status (and the associated checks) don't apply here... */
+ ANIMCHANNEL_NEW_CHANNEL(cdata, type, sce, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ /* return the number of items added to the list */
+ return items;
}
-static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
+static size_t animdata_filter_dopesheet_scene(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, Scene *sce, int filter_mode)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
-
- /* filter data contained under object first */
- BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_SCEC(sce))
- {
- bNodeTree *ntree = sce->nodetree;
- bGPdata *gpd = sce->gpd;
- World *wo = sce->world;
-
- /* Action, Drivers, or NLA for Scene */
- if ((ads->filterflag & ADS_FILTER_NOSCE) == 0) {
- tmp_items += animdata_filter_ds_scene(ac, &tmp_data, ads, sce, filter_mode);
- }
-
- /* world */
- if ((wo) && !(ads->filterflag & ADS_FILTER_NOWOR)) {
- tmp_items += animdata_filter_ds_world(ac, &tmp_data, ads, sce, wo, filter_mode);
- }
-
- /* nodetree */
- if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
- tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)sce, ntree, filter_mode);
- }
-
- /* line styles */
- if ((ads->filterflag & ADS_FILTER_NOLINESTYLE) == 0) {
- tmp_items += animdata_filter_ds_linestyle(ac, &tmp_data, ads, sce, filter_mode);
- }
-
- /* grease pencil */
- if ((gpd) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) {
- tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, gpd, filter_mode);
- }
-
- /* TODO: one day, when sequencer becomes its own datatype, perhaps it should be included here */
- }
- END_ANIMFILTER_SUBCHANNELS;
-
- /* if we collected some channels, add these to the new list... */
- if (tmp_items) {
- /* firstly add object expander if required */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* check if filtering by selection */
- if (ANIMCHANNEL_SELOK((sce->flag & SCE_DS_SELECTED))) {
- /* NOTE: active-status doesn't matter for this! */
- ANIMCHANNEL_NEW_CHANNEL(sce, ANIMTYPE_SCENE, sce, NULL);
- }
- }
-
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
-
- /* return the number of items added */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+
+ /* filter data contained under object first */
+ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_SCEC(sce))
+ {
+ bNodeTree *ntree = sce->nodetree;
+ bGPdata *gpd = sce->gpd;
+ World *wo = sce->world;
+
+ /* Action, Drivers, or NLA for Scene */
+ if ((ads->filterflag & ADS_FILTER_NOSCE) == 0) {
+ tmp_items += animdata_filter_ds_scene(ac, &tmp_data, ads, sce, filter_mode);
+ }
+
+ /* world */
+ if ((wo) && !(ads->filterflag & ADS_FILTER_NOWOR)) {
+ tmp_items += animdata_filter_ds_world(ac, &tmp_data, ads, sce, wo, filter_mode);
+ }
+
+ /* nodetree */
+ if ((ntree) && !(ads->filterflag & ADS_FILTER_NONTREE)) {
+ tmp_items += animdata_filter_ds_nodetree(ac, &tmp_data, ads, (ID *)sce, ntree, filter_mode);
+ }
+
+ /* line styles */
+ if ((ads->filterflag & ADS_FILTER_NOLINESTYLE) == 0) {
+ tmp_items += animdata_filter_ds_linestyle(ac, &tmp_data, ads, sce, filter_mode);
+ }
+
+ /* grease pencil */
+ if ((gpd) && !(ads->filterflag & ADS_FILTER_NOGPENCIL)) {
+ tmp_items += animdata_filter_ds_gpencil(ac, &tmp_data, ads, gpd, filter_mode);
+ }
+
+ /* TODO: one day, when sequencer becomes its own datatype, perhaps it should be included here */
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+
+ /* if we collected some channels, add these to the new list... */
+ if (tmp_items) {
+ /* firstly add object expander if required */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by selection */
+ if (ANIMCHANNEL_SELOK((sce->flag & SCE_DS_SELECTED))) {
+ /* NOTE: active-status doesn't matter for this! */
+ ANIMCHANNEL_NEW_CHANNEL(sce, ANIMTYPE_SCENE, sce, NULL);
+ }
+ }
+
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+
+ /* return the number of items added */
+ return items;
}
-static size_t animdata_filter_ds_movieclip(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, MovieClip *clip, int filter_mode)
+static size_t animdata_filter_ds_movieclip(
+ bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, MovieClip *clip, int filter_mode)
{
- ListBase tmp_data = {NULL, NULL};
- size_t tmp_items = 0;
- size_t items = 0;
- /* add world animation channels */
- BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_MCLIP(clip))
- {
- /* animation data filtering */
- tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)clip, filter_mode);
- }
- END_ANIMFILTER_SUBCHANNELS;
- /* did we find anything? */
- if (tmp_items) {
- /* include data-expand widget first */
- if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
- /* check if filtering by active status */
- if (ANIMCHANNEL_ACTIVEOK(clip)) {
- ANIMCHANNEL_NEW_CHANNEL(clip, ANIMTYPE_DSMCLIP, clip, NULL);
- }
- }
- /* now add the list of collected channels */
- BLI_movelisttolist(anim_data, &tmp_data);
- BLI_assert(BLI_listbase_is_empty(&tmp_data));
- items += tmp_items;
- }
- /* return the number of items added to the list */
- return items;
+ ListBase tmp_data = {NULL, NULL};
+ size_t tmp_items = 0;
+ size_t items = 0;
+ /* add world animation channels */
+ BEGIN_ANIMFILTER_SUBCHANNELS(EXPANDED_MCLIP(clip))
+ {
+ /* animation data filtering */
+ tmp_items += animfilter_block_data(ac, &tmp_data, ads, (ID *)clip, filter_mode);
+ }
+ END_ANIMFILTER_SUBCHANNELS;
+ /* did we find anything? */
+ if (tmp_items) {
+ /* include data-expand widget first */
+ if (filter_mode & ANIMFILTER_LIST_CHANNELS) {
+ /* check if filtering by active status */
+ if (ANIMCHANNEL_ACTIVEOK(clip)) {
+ ANIMCHANNEL_NEW_CHANNEL(clip, ANIMTYPE_DSMCLIP, clip, NULL);
+ }
+ }
+ /* now add the list of collected channels */
+ BLI_movelisttolist(anim_data, &tmp_data);
+ BLI_assert(BLI_listbase_is_empty(&tmp_data));
+ items += tmp_items;
+ }
+ /* return the number of items added to the list */
+ return items;
}
-static size_t animdata_filter_dopesheet_movieclips(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, int filter_mode)
+static size_t animdata_filter_dopesheet_movieclips(bAnimContext *ac,
+ ListBase *anim_data,
+ bDopeSheet *ads,
+ int filter_mode)
{
- size_t items = 0;
- MovieClip *clip;
- for (clip = ac->bmain->movieclips.first; clip != NULL; clip = clip->id.next) {
- /* only show if gpd is used by something... */
- if (ID_REAL_USERS(clip) < 1) {
- continue;
- }
- items += animdata_filter_ds_movieclip(ac, anim_data, ads, clip, filter_mode);
- }
- /* return the number of items added to the list */
- return items;
+ size_t items = 0;
+ MovieClip *clip;
+ for (clip = ac->bmain->movieclips.first; clip != NULL; clip = clip->id.next) {
+ /* only show if gpd is used by something... */
+ if (ID_REAL_USERS(clip) < 1) {
+ continue;
+ }
+ items += animdata_filter_ds_movieclip(ac, anim_data, ads, clip, filter_mode);
+ }
+ /* return the number of items added to the list */
+ return items;
}
/* Helper for animdata_filter_dopesheet() - For checking if an object should be included or not */
static bool animdata_filter_base_is_ok(bDopeSheet *ads, Base *base, int filter_mode)
{
- Object *ob = base->object;
-
- if (base->object == NULL)
- return false;
-
- /* firstly, check if object can be included, by the following factors:
- * - if only visible, must check for layer and also viewport visibility
- * --> while tools may demand only visible, user setting takes priority
- * as user option controls whether sets of channels get included while
- * tool-flag takes into account collapsed/open channels too
- * - if only selected, must check if object is selected
- * - there must be animation data to edit (this is done recursively as we
- * try to add the channels)
- */
- if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
- /* layer visibility - we check both object and base, since these may not be in sync yet */
- if ((base->flag & BASE_VISIBLE) == 0)
- return false;
-
- /* outliner restrict-flag */
- if (ob->restrictflag & OB_RESTRICT_VIEW)
- return false;
- }
-
- /* if only F-Curves with visible flags set can be shown, check that
- * datablock hasn't been set to invisible
- */
- if (filter_mode & ANIMFILTER_CURVE_VISIBLE) {
- if ((ob->adt) && (ob->adt->flag & ADT_CURVES_NOT_VISIBLE))
- return false;
- }
-
- /* Pinned curves are visible regardless of selection flags. */
- if ((ob->adt) && (ob->adt->flag & ADT_CURVES_ALWAYS_VISIBLE)) {
- return true;
- }
-
- /* Special case.
- * We don't do recursive checks for pin, but we need to deal with tricky
- * setup like animated camera lens without animated camera location.
- * Without such special handle here we wouldn't be able to bin such
- * camera data only animation to the editor.
- */
- if (ob->adt == NULL && ob->data != NULL) {
- AnimData *data_adt = BKE_animdata_from_id(ob->data);
- if (data_adt != NULL && (data_adt->flag & ADT_CURVES_ALWAYS_VISIBLE)) {
- return true;
- }
- }
-
- /* check selection and object type filters */
- if ((ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & BASE_SELECTED) /*|| (base == sce->basact)*/)) {
- /* only selected should be shown */
- return false;
- }
-
- /* check if object belongs to the filtering group if option to filter
- * objects by the grouped status is on
- * - used to ease the process of doing multiple-character choreographies
- */
- if (ads->filter_grp != NULL) {
- if (BKE_collection_has_object_recursive(ads->filter_grp, ob) == 0)
- return false;
- }
-
- /* no reason to exclude this object... */
- return true;
+ Object *ob = base->object;
+
+ if (base->object == NULL)
+ return false;
+
+ /* firstly, check if object can be included, by the following factors:
+ * - if only visible, must check for layer and also viewport visibility
+ * --> while tools may demand only visible, user setting takes priority
+ * as user option controls whether sets of channels get included while
+ * tool-flag takes into account collapsed/open channels too
+ * - if only selected, must check if object is selected
+ * - there must be animation data to edit (this is done recursively as we
+ * try to add the channels)
+ */
+ if ((filter_mode & ANIMFILTER_DATA_VISIBLE) && !(ads->filterflag & ADS_FILTER_INCL_HIDDEN)) {
+ /* layer visibility - we check both object and base, since these may not be in sync yet */
+ if ((base->flag & BASE_VISIBLE) == 0)
+ return false;
+
+ /* outliner restrict-flag */
+ if (ob->restrictflag & OB_RESTRICT_VIEW)
+ return false;
+ }
+
+ /* if only F-Curves with visible flags set can be shown, check that
+ * datablock hasn't been set to invisible
+ */
+ if (filter_mode & ANIMFILTER_CURVE_VISIBLE) {
+ if ((ob->adt) && (ob->adt->flag & ADT_CURVES_NOT_VISIBLE))
+ return false;
+ }
+
+ /* Pinned curves are visible regardless of selection flags. */
+ if ((ob->adt) && (ob->adt->flag & ADT_CURVES_ALWAYS_VISIBLE)) {
+ return true;
+ }
+
+ /* Special case.
+ * We don't do recursive checks for pin, but we need to deal with tricky
+ * setup like animated camera lens without animated camera location.
+ * Without such special handle here we wouldn't be able to bin such
+ * camera data only animation to the editor.
+ */
+ if (ob->adt == NULL && ob->data != NULL) {
+ AnimData *data_adt = BKE_animdata_from_id(ob->data);
+ if (data_adt != NULL && (data_adt->flag & ADT_CURVES_ALWAYS_VISIBLE)) {
+ return true;
+ }
+ }
+
+ /* check selection and object type filters */
+ if ((ads->filterflag & ADS_FILTER_ONLYSEL) &&
+ !((base->flag & BASE_SELECTED) /*|| (base == sce->basact)*/)) {
+ /* only selected should be shown */
+ return false;
+ }
+
+ /* check if object belongs to the filtering group if option to filter
+ * objects by the grouped status is on
+ * - used to ease the process of doing multiple-character choreographies
+ */
+ if (ads->filter_grp != NULL) {
+ if (BKE_collection_has_object_recursive(ads->filter_grp, ob) == 0)
+ return false;
+ }
+
+ /* no reason to exclude this object... */
+ return true;
}
/* Helper for animdata_filter_ds_sorted_bases() - Comparison callback for two Base pointers... */
static int ds_base_sorting_cmp(const void *base1_ptr, const void *base2_ptr)
{
- const Base *b1 = *((const Base **)base1_ptr);
- const Base *b2 = *((const Base **)base2_ptr);
+ const Base *b1 = *((const Base **)base1_ptr);
+ const Base *b2 = *((const Base **)base2_ptr);
- return strcmp(b1->object->id.name + 2, b2->object->id.name + 2);
+ return strcmp(b1->object->id.name + 2, b2->object->id.name + 2);
}
/* Get a sorted list of all the bases - for inclusion in dopesheet (when drawing channels) */
-static Base **animdata_filter_ds_sorted_bases(bDopeSheet *ads, ViewLayer *view_layer, int filter_mode, size_t *r_usable_bases)
+static Base **animdata_filter_ds_sorted_bases(bDopeSheet *ads,
+ ViewLayer *view_layer,
+ int filter_mode,
+ size_t *r_usable_bases)
{
- /* Create an array with space for all the bases, but only containing the usable ones */
- size_t tot_bases = BLI_listbase_count(&view_layer->object_bases);
- size_t num_bases = 0;
-
- Base **sorted_bases = MEM_mallocN(sizeof(Base *) * tot_bases, "Dopesheet Usable Sorted Bases");
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (animdata_filter_base_is_ok(ads, base, filter_mode)) {
- sorted_bases[num_bases++] = base;
- }
- }
-
- /* Sort this list of pointers (based on the names) */
- qsort(sorted_bases, num_bases, sizeof(Base *), ds_base_sorting_cmp);
-
- /* Return list of sorted bases */
- *r_usable_bases = num_bases;
- return sorted_bases;
+ /* Create an array with space for all the bases, but only containing the usable ones */
+ size_t tot_bases = BLI_listbase_count(&view_layer->object_bases);
+ size_t num_bases = 0;
+
+ Base **sorted_bases = MEM_mallocN(sizeof(Base *) * tot_bases, "Dopesheet Usable Sorted Bases");
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if (animdata_filter_base_is_ok(ads, base, filter_mode)) {
+ sorted_bases[num_bases++] = base;
+ }
+ }
+
+ /* Sort this list of pointers (based on the names) */
+ qsort(sorted_bases, num_bases, sizeof(Base *), ds_base_sorting_cmp);
+
+ /* Return list of sorted bases */
+ *r_usable_bases = num_bases;
+ return sorted_bases;
}
-
// TODO: implement pinning... (if and when pinning is done, what we need to do is to provide freeing mechanisms - to protect against data that was deleted)
-static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, int filter_mode)
+static size_t animdata_filter_dopesheet(bAnimContext *ac,
+ ListBase *anim_data,
+ bDopeSheet *ads,
+ int filter_mode)
{
- Scene *scene = (Scene *)ads->source;
- ViewLayer *view_layer = (ViewLayer *)ac->view_layer;
- size_t items = 0;
-
- /* check that we do indeed have a scene */
- if ((ads->source == NULL) || (GS(ads->source->name) != ID_SCE)) {
- printf("Dope Sheet Error: No scene!\n");
- if (G.debug & G_DEBUG)
- printf("\tPointer = %p, Name = '%s'\n", (void *)ads->source, (ads->source) ? ads->source->name : NULL);
- return 0;
- }
-
- /* augment the filter-flags with settings based on the dopesheet filterflags
- * so that some temp settings can get added automagically...
- */
- if (ads->filterflag & ADS_FILTER_SELEDIT) {
- /* only selected F-Curves should get their keyframes considered for editability */
- filter_mode |= ANIMFILTER_SELEDIT;
- }
-
- /* Cache files level animations (frame duration and such). */
- if (!(ads->filterflag2 & ADS_FILTER_NOCACHEFILES) && !(ads->filterflag & ADS_FILTER_ONLYSEL)) {
- CacheFile *cache_file = ac->bmain->cachefiles.first;
- for (; cache_file; cache_file = cache_file->id.next) {
- items += animdata_filter_ds_cachefile(ac, anim_data, ads, cache_file, filter_mode);
- }
- }
-
- /* movie clip's animation */
- items += animdata_filter_dopesheet_movieclips(ac, anim_data, ads, filter_mode);
-
- /* scene-linked animation - e.g. world, compositing nodes, scene anim (including sequencer currently) */
- items += animdata_filter_dopesheet_scene(ac, anim_data, ads, scene, filter_mode);
-
- /* If filtering for channel drawing, we want the objects in alphabetical order,
- * to make it easier to predict where items are in the hierarchy
- * - This order only really matters if we need to show all channels in the list (e.g. for drawing)
- * (XXX: What about lingering "active" flags? The order may now become unpredictable)
- * - Don't do this if this behavior has been turned off (i.e. due to it being too slow)
- * - Don't do this if there's just a single object
- */
- if ((filter_mode & ANIMFILTER_LIST_CHANNELS) && !(ads->flag & ADS_FLAG_NO_DB_SORT) &&
- (view_layer->object_bases.first != view_layer->object_bases.last))
- {
- /* Filter list of bases (i.e. objects), sort them, then add their contents normally... */
- // TODO: Cache the old sorted order - if the set of bases hasn't changed, don't re-sort...
- Base **sorted_bases;
- size_t num_bases;
-
- sorted_bases = animdata_filter_ds_sorted_bases(ads, view_layer, filter_mode, &num_bases);
- if (sorted_bases) {
- /* Add the necessary channels for these bases... */
- for (size_t i = 0; i < num_bases; i++) {
- items += animdata_filter_dopesheet_ob(ac, anim_data, ads, sorted_bases[i], filter_mode);
- }
-
- // TODO: store something to validate whether any changes are needed?
-
- /* free temporary data */
- MEM_freeN(sorted_bases);
- }
- }
- else {
- /* Filter and add contents of each base (i.e. object) without them sorting first
- * NOTE: This saves performance in cases where order doesn't matter
- */
- for (Base *base = view_layer->object_bases.first; base; base = base->next) {
- if (animdata_filter_base_is_ok(ads, base, filter_mode)) {
- /* since we're still here, this object should be usable */
- items += animdata_filter_dopesheet_ob(ac, anim_data, ads, base, filter_mode);
- }
- }
- }
-
- /* return the number of items in the list */
- return items;
+ Scene *scene = (Scene *)ads->source;
+ ViewLayer *view_layer = (ViewLayer *)ac->view_layer;
+ size_t items = 0;
+
+ /* check that we do indeed have a scene */
+ if ((ads->source == NULL) || (GS(ads->source->name) != ID_SCE)) {
+ printf("Dope Sheet Error: No scene!\n");
+ if (G.debug & G_DEBUG)
+ printf("\tPointer = %p, Name = '%s'\n",
+ (void *)ads->source,
+ (ads->source) ? ads->source->name : NULL);
+ return 0;
+ }
+
+ /* augment the filter-flags with settings based on the dopesheet filterflags
+ * so that some temp settings can get added automagically...
+ */
+ if (ads->filterflag & ADS_FILTER_SELEDIT) {
+ /* only selected F-Curves should get their keyframes considered for editability */
+ filter_mode |= ANIMFILTER_SELEDIT;
+ }
+
+ /* Cache files level animations (frame duration and such). */
+ if (!(ads->filterflag2 & ADS_FILTER_NOCACHEFILES) && !(ads->filterflag & ADS_FILTER_ONLYSEL)) {
+ CacheFile *cache_file = ac->bmain->cachefiles.first;
+ for (; cache_file; cache_file = cache_file->id.next) {
+ items += animdata_filter_ds_cachefile(ac, anim_data, ads, cache_file, filter_mode);
+ }
+ }
+
+ /* movie clip's animation */
+ items += animdata_filter_dopesheet_movieclips(ac, anim_data, ads, filter_mode);
+
+ /* scene-linked animation - e.g. world, compositing nodes, scene anim (including sequencer currently) */
+ items += animdata_filter_dopesheet_scene(ac, anim_data, ads, scene, filter_mode);
+
+ /* If filtering for channel drawing, we want the objects in alphabetical order,
+ * to make it easier to predict where items are in the hierarchy
+ * - This order only really matters if we need to show all channels in the list (e.g. for drawing)
+ * (XXX: What about lingering "active" flags? The order may now become unpredictable)
+ * - Don't do this if this behavior has been turned off (i.e. due to it being too slow)
+ * - Don't do this if there's just a single object
+ */
+ if ((filter_mode & ANIMFILTER_LIST_CHANNELS) && !(ads->flag & ADS_FLAG_NO_DB_SORT) &&
+ (view_layer->object_bases.first != view_layer->object_bases.last)) {
+ /* Filter list of bases (i.e. objects), sort them, then add their contents normally... */
+ // TODO: Cache the old sorted order - if the set of bases hasn't changed, don't re-sort...
+ Base **sorted_bases;
+ size_t num_bases;
+
+ sorted_bases = animdata_filter_ds_sorted_bases(ads, view_layer, filter_mode, &num_bases);
+ if (sorted_bases) {
+ /* Add the necessary channels for these bases... */
+ for (size_t i = 0; i < num_bases; i++) {
+ items += animdata_filter_dopesheet_ob(ac, anim_data, ads, sorted_bases[i], filter_mode);
+ }
+
+ // TODO: store something to validate whether any changes are needed?
+
+ /* free temporary data */
+ MEM_freeN(sorted_bases);
+ }
+ }
+ else {
+ /* Filter and add contents of each base (i.e. object) without them sorting first
+ * NOTE: This saves performance in cases where order doesn't matter
+ */
+ for (Base *base = view_layer->object_bases.first; base; base = base->next) {
+ if (animdata_filter_base_is_ok(ads, base, filter_mode)) {
+ /* since we're still here, this object should be usable */
+ items += animdata_filter_dopesheet_ob(ac, anim_data, ads, base, filter_mode);
+ }
+ }
+ }
+
+ /* return the number of items in the list */
+ return items;
}
/* Summary track for DopeSheet/Action Editor
* - return code is whether the summary lets the other channels get drawn
*/
-static short animdata_filter_dopesheet_summary(bAnimContext *ac, ListBase *anim_data, int filter_mode, size_t *items)
+static short animdata_filter_dopesheet_summary(bAnimContext *ac,
+ ListBase *anim_data,
+ int filter_mode,
+ size_t *items)
{
- bDopeSheet *ads = NULL;
-
- /* get the DopeSheet information to use
- * - we should only need to deal with the DopeSheet/Action Editor,
- * since all the other Animation Editors won't have this concept
- * being applicable.
- */
- if ((ac && ac->sl) && (ac->spacetype == SPACE_ACTION)) {
- SpaceAction *saction = (SpaceAction *)ac->sl;
- ads = &saction->ads;
- }
- else {
- /* invalid space type - skip this summary channels */
- return 1;
- }
-
- /* dopesheet summary
- * - only for drawing and/or selecting keyframes in channels, but not for real editing
- * - only useful for DopeSheet/Action/etc. editors where it is actually useful
- */
- if ((filter_mode & ANIMFILTER_LIST_CHANNELS) && (ads->filterflag & ADS_FILTER_SUMMARY)) {
- bAnimListElem *ale = make_new_animlistelem(ac, ANIMTYPE_SUMMARY, NULL, NULL);
- if (ale) {
- BLI_addtail(anim_data, ale);
- (*items)++;
- }
-
- /* if summary is collapsed, don't show other channels beneath this
- * - this check is put inside the summary check so that it doesn't interfere with normal operation
- */
- if (ads->flag & ADS_FLAG_SUMMARY_COLLAPSED)
- return 0;
- }
-
- /* the other channels beneath this can be shown */
- return 1;
+ bDopeSheet *ads = NULL;
+
+ /* get the DopeSheet information to use
+ * - we should only need to deal with the DopeSheet/Action Editor,
+ * since all the other Animation Editors won't have this concept
+ * being applicable.
+ */
+ if ((ac && ac->sl) && (ac->spacetype == SPACE_ACTION)) {
+ SpaceAction *saction = (SpaceAction *)ac->sl;
+ ads = &saction->ads;
+ }
+ else {
+ /* invalid space type - skip this summary channels */
+ return 1;
+ }
+
+ /* dopesheet summary
+ * - only for drawing and/or selecting keyframes in channels, but not for real editing
+ * - only useful for DopeSheet/Action/etc. editors where it is actually useful
+ */
+ if ((filter_mode & ANIMFILTER_LIST_CHANNELS) && (ads->filterflag & ADS_FILTER_SUMMARY)) {
+ bAnimListElem *ale = make_new_animlistelem(ac, ANIMTYPE_SUMMARY, NULL, NULL);
+ if (ale) {
+ BLI_addtail(anim_data, ale);
+ (*items)++;
+ }
+
+ /* if summary is collapsed, don't show other channels beneath this
+ * - this check is put inside the summary check so that it doesn't interfere with normal operation
+ */
+ if (ads->flag & ADS_FLAG_SUMMARY_COLLAPSED)
+ return 0;
+ }
+
+ /* the other channels beneath this can be shown */
+ return 1;
}
/* ......................... */
/* filter data associated with a channel - usually for handling summary-channels in DopeSheet */
-static size_t animdata_filter_animchan(bAnimContext *ac, ListBase *anim_data, bDopeSheet *ads, bAnimListElem *channel, int filter_mode)
+static size_t animdata_filter_animchan(bAnimContext *ac,
+ ListBase *anim_data,
+ bDopeSheet *ads,
+ bAnimListElem *channel,
+ int filter_mode)
{
- size_t items = 0;
-
- /* data to filter depends on channel type */
- /* NOTE: only common channel-types have been handled for now. More can be added as necessary */
- switch (channel->type) {
- case ANIMTYPE_SUMMARY:
- items += animdata_filter_dopesheet(ac, anim_data, ads, filter_mode);
- break;
-
- case ANIMTYPE_SCENE:
- items += animdata_filter_dopesheet_scene(ac, anim_data, ads, channel->data, filter_mode);
- break;
-
- case ANIMTYPE_OBJECT:
- items += animdata_filter_dopesheet_ob(ac, anim_data, ads, channel->data, filter_mode);
- break;
-
- case ANIMTYPE_DSCACHEFILE:
- items += animdata_filter_ds_cachefile(ac, anim_data, ads, channel->data, filter_mode);
- break;
-
- case ANIMTYPE_ANIMDATA:
- items += animfilter_block_data(ac, anim_data, ads, channel->id, filter_mode);
- break;
-
- default:
- printf("ERROR: Unsupported channel type (%d) in animdata_filter_animchan()\n", channel->type);
- break;
- }
-
- return items;
+ size_t items = 0;
+
+ /* data to filter depends on channel type */
+ /* NOTE: only common channel-types have been handled for now. More can be added as necessary */
+ switch (channel->type) {
+ case ANIMTYPE_SUMMARY:
+ items += animdata_filter_dopesheet(ac, anim_data, ads, filter_mode);
+ break;
+
+ case ANIMTYPE_SCENE:
+ items += animdata_filter_dopesheet_scene(ac, anim_data, ads, channel->data, filter_mode);
+ break;
+
+ case ANIMTYPE_OBJECT:
+ items += animdata_filter_dopesheet_ob(ac, anim_data, ads, channel->data, filter_mode);
+ break;
+
+ case ANIMTYPE_DSCACHEFILE:
+ items += animdata_filter_ds_cachefile(ac, anim_data, ads, channel->data, filter_mode);
+ break;
+
+ case ANIMTYPE_ANIMDATA:
+ items += animfilter_block_data(ac, anim_data, ads, channel->id, filter_mode);
+ break;
+
+ default:
+ printf("ERROR: Unsupported channel type (%d) in animdata_filter_animchan()\n",
+ channel->type);
+ break;
+ }
+
+ return items;
}
/* ----------- Cleanup API --------------- */
@@ -3128,57 +3211,57 @@ static size_t animdata_filter_animchan(bAnimContext *ac, ListBase *anim_data, bD
/* Remove entries with invalid types in animation channel list */
static size_t animdata_filter_remove_invalid(ListBase *anim_data)
{
- bAnimListElem *ale, *next;
- size_t items = 0;
+ bAnimListElem *ale, *next;
+ size_t items = 0;
- /* only keep entries with valid types */
- for (ale = anim_data->first; ale; ale = next) {
- next = ale->next;
+ /* only keep entries with valid types */
+ for (ale = anim_data->first; ale; ale = next) {
+ next = ale->next;
- if (ale->type == ANIMTYPE_NONE)
- BLI_freelinkN(anim_data, ale);
- else
- items++;
- }
+ if (ale->type == ANIMTYPE_NONE)
+ BLI_freelinkN(anim_data, ale);
+ else
+ items++;
+ }
- return items;
+ return items;
}
/* Remove duplicate entries in animation channel list */
static size_t animdata_filter_remove_duplis(ListBase *anim_data)
{
- bAnimListElem *ale, *next;
- GSet *gs;
- size_t items = 0;
-
- /* build new hashtable to efficiently store and retrieve which entries have been
- * encountered already while searching
- */
- gs = BLI_gset_ptr_new(__func__);
-
- /* loop through items, removing them from the list if a similar item occurs already */
- for (ale = anim_data->first; ale; ale = next) {
- next = ale->next;
-
- /* check if hash has any record of an entry like this
- * - just use ale->data for now, though it would be nicer to involve
- * ale->type in combination too to capture corner cases (where same data performs differently)
- */
- if (BLI_gset_add(gs, ale->data)) {
- /* this entry is 'unique' and can be kept */
- items++;
- }
- else {
- /* this entry isn't needed anymore */
- BLI_freelinkN(anim_data, ale);
- }
- }
-
- /* free the hash... */
- BLI_gset_free(gs, NULL);
-
- /* return the number of items still in the list */
- return items;
+ bAnimListElem *ale, *next;
+ GSet *gs;
+ size_t items = 0;
+
+ /* build new hashtable to efficiently store and retrieve which entries have been
+ * encountered already while searching
+ */
+ gs = BLI_gset_ptr_new(__func__);
+
+ /* loop through items, removing them from the list if a similar item occurs already */
+ for (ale = anim_data->first; ale; ale = next) {
+ next = ale->next;
+
+ /* check if hash has any record of an entry like this
+ * - just use ale->data for now, though it would be nicer to involve
+ * ale->type in combination too to capture corner cases (where same data performs differently)
+ */
+ if (BLI_gset_add(gs, ale->data)) {
+ /* this entry is 'unique' and can be kept */
+ items++;
+ }
+ else {
+ /* this entry isn't needed anymore */
+ BLI_freelinkN(anim_data, ale);
+ }
+ }
+
+ /* free the hash... */
+ BLI_gset_free(gs, NULL);
+
+ /* return the number of items still in the list */
+ return items;
}
/* ----------- Public API --------------- */
@@ -3190,128 +3273,125 @@ static size_t animdata_filter_remove_duplis(ListBase *anim_data)
* will be placed for use.
* filter_mode: how should the data be filtered - bitmapping accessed flags
*/
-size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, eAnimFilter_Flags filter_mode, void *data, eAnimCont_Types datatype)
+size_t ANIM_animdata_filter(bAnimContext *ac,
+ ListBase *anim_data,
+ eAnimFilter_Flags filter_mode,
+ void *data,
+ eAnimCont_Types datatype)
{
- size_t items = 0;
-
- /* only filter data if there's somewhere to put it */
- if (data && anim_data) {
- /* firstly filter the data */
- switch (datatype) {
- /* Action-Editing Modes */
- case ANIMCONT_ACTION: /* 'Action Editor' */
- {
- Object *obact = ac->obact;
- SpaceAction *saction = (SpaceAction *)ac->sl;
- bDopeSheet *ads = (saction) ? &saction->ads : NULL;
-
- /* specially check for AnimData filter... [#36687] */
- if (UNLIKELY(filter_mode & ANIMFILTER_ANIMDATA)) {
- /* all channels here are within the same AnimData block, hence this special case */
- if (LIKELY(obact->adt)) {
- ANIMCHANNEL_NEW_CHANNEL(obact->adt, ANIMTYPE_ANIMDATA, (ID *)obact, NULL);
- }
- }
- else {
- /* the check for the DopeSheet summary is included here since the summary works here too */
- if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
- items += animfilter_action(ac, anim_data, ads, data, filter_mode, (ID *)obact);
- }
-
- break;
- }
- case ANIMCONT_SHAPEKEY: /* 'ShapeKey Editor' */
- {
- Key *key = (Key *)data;
-
- /* specially check for AnimData filter... [#36687] */
- if (UNLIKELY(filter_mode & ANIMFILTER_ANIMDATA)) {
- /* all channels here are within the same AnimData block, hence this special case */
- if (LIKELY(key->adt)) {
- ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, (ID *)key, NULL);
- }
- }
- else {
- /* the check for the DopeSheet summary is included here since the summary works here too */
- if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
- items = animdata_filter_shapekey(ac, anim_data, key, filter_mode);
- }
-
- break;
- }
-
-
- /* Modes for Specialty Data Types (i.e. not keyframes) */
- case ANIMCONT_GPENCIL:
- {
- if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
- items = animdata_filter_gpencil(ac, anim_data, data, filter_mode);
- break;
- }
- case ANIMCONT_MASK:
- {
- if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
- items = animdata_filter_mask(ac->bmain, anim_data, data, filter_mode);
- break;
- }
-
-
- /* DopeSheet Based Modes */
- case ANIMCONT_DOPESHEET: /* 'DopeSheet Editor' */
- {
- /* the DopeSheet editor is the primary place where the DopeSheet summaries are useful */
- if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
- items += animdata_filter_dopesheet(ac, anim_data, data, filter_mode);
- break;
- }
- case ANIMCONT_FCURVES: /* Graph Editor -> F-Curves/Animation Editing */
- case ANIMCONT_DRIVERS: /* Graph Editor -> Drivers Editing */
- case ANIMCONT_NLA: /* NLA Editor */
- {
- /* all of these editors use the basic DopeSheet data for filtering options,
- * but don't have all the same features */
- items = animdata_filter_dopesheet(ac, anim_data, data, filter_mode);
- break;
- }
-
-
- /* Timeline Mode - Basically the same as dopesheet, except we only have the summary for now */
- case ANIMCONT_TIMELINE:
- {
- /* the DopeSheet editor is the primary place where the DopeSheet summaries are useful */
- if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
- items += animdata_filter_dopesheet(ac, anim_data, data, filter_mode);
- break;
- }
-
- /* Special/Internal Use */
- case ANIMCONT_CHANNEL: /* animation channel */
- {
- bDopeSheet *ads = ac->ads;
-
- /* based on the channel type, filter relevant data for this */
- items = animdata_filter_animchan(ac, anim_data, ads, data, filter_mode);
- break;
- }
-
- /* unhandled */
- default:
- {
- printf("ANIM_animdata_filter() - Invalid datatype argument %u\n", datatype);
- break;
- }
- }
-
- /* remove any 'weedy' entries */
- items = animdata_filter_remove_invalid(anim_data);
-
- /* remove duplicates (if required) */
- if (filter_mode & ANIMFILTER_NODUPLIS)
- items = animdata_filter_remove_duplis(anim_data);
- }
-
- /* return the number of items in the list */
- return items;
+ size_t items = 0;
+
+ /* only filter data if there's somewhere to put it */
+ if (data && anim_data) {
+ /* firstly filter the data */
+ switch (datatype) {
+ /* Action-Editing Modes */
+ case ANIMCONT_ACTION: /* 'Action Editor' */
+ {
+ Object *obact = ac->obact;
+ SpaceAction *saction = (SpaceAction *)ac->sl;
+ bDopeSheet *ads = (saction) ? &saction->ads : NULL;
+
+ /* specially check for AnimData filter... [#36687] */
+ if (UNLIKELY(filter_mode & ANIMFILTER_ANIMDATA)) {
+ /* all channels here are within the same AnimData block, hence this special case */
+ if (LIKELY(obact->adt)) {
+ ANIMCHANNEL_NEW_CHANNEL(obact->adt, ANIMTYPE_ANIMDATA, (ID *)obact, NULL);
+ }
+ }
+ else {
+ /* the check for the DopeSheet summary is included here since the summary works here too */
+ if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
+ items += animfilter_action(ac, anim_data, ads, data, filter_mode, (ID *)obact);
+ }
+
+ break;
+ }
+ case ANIMCONT_SHAPEKEY: /* 'ShapeKey Editor' */
+ {
+ Key *key = (Key *)data;
+
+ /* specially check for AnimData filter... [#36687] */
+ if (UNLIKELY(filter_mode & ANIMFILTER_ANIMDATA)) {
+ /* all channels here are within the same AnimData block, hence this special case */
+ if (LIKELY(key->adt)) {
+ ANIMCHANNEL_NEW_CHANNEL(key->adt, ANIMTYPE_ANIMDATA, (ID *)key, NULL);
+ }
+ }
+ else {
+ /* the check for the DopeSheet summary is included here since the summary works here too */
+ if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
+ items = animdata_filter_shapekey(ac, anim_data, key, filter_mode);
+ }
+
+ break;
+ }
+
+ /* Modes for Specialty Data Types (i.e. not keyframes) */
+ case ANIMCONT_GPENCIL: {
+ if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
+ items = animdata_filter_gpencil(ac, anim_data, data, filter_mode);
+ break;
+ }
+ case ANIMCONT_MASK: {
+ if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
+ items = animdata_filter_mask(ac->bmain, anim_data, data, filter_mode);
+ break;
+ }
+
+ /* DopeSheet Based Modes */
+ case ANIMCONT_DOPESHEET: /* 'DopeSheet Editor' */
+ {
+ /* the DopeSheet editor is the primary place where the DopeSheet summaries are useful */
+ if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
+ items += animdata_filter_dopesheet(ac, anim_data, data, filter_mode);
+ break;
+ }
+ case ANIMCONT_FCURVES: /* Graph Editor -> F-Curves/Animation Editing */
+ case ANIMCONT_DRIVERS: /* Graph Editor -> Drivers Editing */
+ case ANIMCONT_NLA: /* NLA Editor */
+ {
+ /* all of these editors use the basic DopeSheet data for filtering options,
+ * but don't have all the same features */
+ items = animdata_filter_dopesheet(ac, anim_data, data, filter_mode);
+ break;
+ }
+
+ /* Timeline Mode - Basically the same as dopesheet, except we only have the summary for now */
+ case ANIMCONT_TIMELINE: {
+ /* the DopeSheet editor is the primary place where the DopeSheet summaries are useful */
+ if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items))
+ items += animdata_filter_dopesheet(ac, anim_data, data, filter_mode);
+ break;
+ }
+
+ /* Special/Internal Use */
+ case ANIMCONT_CHANNEL: /* animation channel */
+ {
+ bDopeSheet *ads = ac->ads;
+
+ /* based on the channel type, filter relevant data for this */
+ items = animdata_filter_animchan(ac, anim_data, ads, data, filter_mode);
+ break;
+ }
+
+ /* unhandled */
+ default: {
+ printf("ANIM_animdata_filter() - Invalid datatype argument %u\n", datatype);
+ break;
+ }
+ }
+
+ /* remove any 'weedy' entries */
+ items = animdata_filter_remove_invalid(anim_data);
+
+ /* remove duplicates (if required) */
+ if (filter_mode & ANIMFILTER_NODUPLIS)
+ items = animdata_filter_remove_duplis(anim_data);
+ }
+
+ /* return the number of items in the list */
+ return items;
}
/* ************************************************************ */
diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h
index 4661d19378a..7fb5540fdf7 100644
--- a/source/blender/editors/animation/anim_intern.h
+++ b/source/blender/editors/animation/anim_intern.h
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
#ifndef __ANIM_INTERN_H__
#define __ANIM_INTERN_H__
@@ -79,4 +78,4 @@ void ANIM_OT_driver_button_edit(struct wmOperatorType *ot);
void ANIM_OT_copy_driver_button(struct wmOperatorType *ot);
void ANIM_OT_paste_driver_button(struct wmOperatorType *ot);
-#endif /* __ANIM_INTERN_H__ */
+#endif /* __ANIM_INTERN_H__ */
diff --git a/source/blender/editors/animation/anim_ipo_utils.c b/source/blender/editors/animation/anim_ipo_utils.c
index 03cc4855a4b..fd22fa16fe8 100644
--- a/source/blender/editors/animation/anim_ipo_utils.c
+++ b/source/blender/editors/animation/anim_ipo_utils.c
@@ -21,14 +21,12 @@
* \ingroup edanimation
*/
-
/* This file contains code for presenting F-Curves and other animation data
* in the UI (especially for use in the Animation Editors).
*
* -- Joshua Leung, Dec 2008
*/
-
#include "MEM_guardedalloc.h"
#include "BLI_blenlib.h"
@@ -51,172 +49,176 @@
*/
int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
{
- int icon = 0;
-
- /* sanity checks */
- if (name == NULL)
- return icon;
- else if (ELEM(NULL, id, fcu, fcu->rna_path)) {
- if (fcu == NULL)
- strcpy(name, IFACE_("<invalid>"));
- else if (fcu->rna_path == NULL)
- strcpy(name, IFACE_("<no path>"));
- else /* id == NULL */
- BLI_snprintf(name, 256, "%s[%d]", fcu->rna_path, fcu->array_index);
- }
- else {
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
-
- /* get RNA pointer, and resolve the path */
- RNA_id_pointer_create(id, &id_ptr);
-
- /* try to resolve the path */
- if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
- const char *structname = NULL, *propname = NULL;
- char arrayindbuf[16];
- const char *arrayname = NULL;
- short free_structname = 0;
-
- /* For now, name will consist of 3 parts: struct-name, property name, array index
- * There are several options possible:
- * 1) <struct-name>.<property-name>.<array-index>
- * i.e. Bone1.Location.X, or Object.Location.X
- * 2) <array-index> <property-name> (<struct name>)
- * i.e. X Location (Bone1), or X Location (Object)
- *
- * Currently, option 2 is in use, to try and make it easier to quickly identify F-Curves (it does have
- * problems with looking rather odd though). Option 1 is better in terms of revealing a consistent sense of
- * hierarchy though, which isn't so clear with option 2.
- */
-
- /* for structname
- * - as base, we use a custom name from the structs if one is available
- * - however, if we're showing subdata of bones (probably there will be other exceptions later)
- * need to include that info too since it gets confusing otherwise
- * - if a pointer just refers to the ID-block, then don't repeat this info
- * since this just introduces clutter
- */
- if (strstr(fcu->rna_path, "bones") && strstr(fcu->rna_path, "constraints")) {
- /* perform string 'chopping' to get "Bone Name : Constraint Name" */
- char *pchanName = BLI_str_quoted_substrN(fcu->rna_path, "bones[");
- char *constName = BLI_str_quoted_substrN(fcu->rna_path, "constraints[");
-
- /* assemble the string to display in the UI... */
- structname = BLI_sprintfN("%s : %s", pchanName, constName);
- free_structname = 1;
-
- /* free the temp names */
- if (pchanName) MEM_freeN(pchanName);
- if (constName) MEM_freeN(constName);
- }
- else if (ptr.data != ptr.id.data) {
- PropertyRNA *nameprop = RNA_struct_name_property(ptr.type);
- if (nameprop) {
- /* this gets a string which will need to be freed */
- structname = RNA_property_string_get_alloc(&ptr, nameprop, NULL, 0, NULL);
- free_structname = 1;
- }
- else
- structname = RNA_struct_ui_name(ptr.type);
- }
-
- /* Property Name is straightforward */
- propname = RNA_property_ui_name(prop);
-
- /* Array Index - only if applicable */
- if (RNA_property_array_check(prop)) {
- char c = RNA_property_array_item_char(prop, fcu->array_index);
-
- /* we need to write the index to a temp buffer (in py syntax) */
- if (c) BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "%c ", c);
- else BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "[%d]", fcu->array_index);
-
- arrayname = &arrayindbuf[0];
- }
- else {
- /* no array index */
- arrayname = "";
- }
-
- /* putting this all together into the buffer */
- /* XXX we need to check for invalid names...
- * XXX the name length limit needs to be passed in or as some define */
- if (structname)
- BLI_snprintf(name, 256, "%s%s (%s)", arrayname, propname, structname);
- else
- BLI_snprintf(name, 256, "%s%s", arrayname, propname);
-
- /* free temp name if nameprop is set */
- if (free_structname)
- MEM_freeN((void *)structname);
-
-
- /* Icon for this property's owner:
- * use the struct's icon if it is set
- */
- icon = RNA_struct_ui_icon(ptr.type);
-
- /* valid path - remove the invalid tag since we now know how to use it saving
- * users manual effort to reenable using "Revive Disabled FCurves" [#29629]
- */
- fcu->flag &= ~FCURVE_DISABLED;
- }
- else {
- /* invalid path */
- BLI_snprintf(name, 256, "\"%s[%d]\"", fcu->rna_path, fcu->array_index);
-
- /* icon for this should be the icon for the base ID */
- /* TODO: or should we just use the error icon? */
- icon = RNA_struct_ui_icon(id_ptr.type);
-
- /* tag F-Curve as disabled - as not usable path */
- fcu->flag |= FCURVE_DISABLED;
- }
- }
-
- /* return the icon that the active data had */
- return icon;
+ int icon = 0;
+
+ /* sanity checks */
+ if (name == NULL)
+ return icon;
+ else if (ELEM(NULL, id, fcu, fcu->rna_path)) {
+ if (fcu == NULL)
+ strcpy(name, IFACE_("<invalid>"));
+ else if (fcu->rna_path == NULL)
+ strcpy(name, IFACE_("<no path>"));
+ else /* id == NULL */
+ BLI_snprintf(name, 256, "%s[%d]", fcu->rna_path, fcu->array_index);
+ }
+ else {
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+
+ /* get RNA pointer, and resolve the path */
+ RNA_id_pointer_create(id, &id_ptr);
+
+ /* try to resolve the path */
+ if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
+ const char *structname = NULL, *propname = NULL;
+ char arrayindbuf[16];
+ const char *arrayname = NULL;
+ short free_structname = 0;
+
+ /* For now, name will consist of 3 parts: struct-name, property name, array index
+ * There are several options possible:
+ * 1) <struct-name>.<property-name>.<array-index>
+ * i.e. Bone1.Location.X, or Object.Location.X
+ * 2) <array-index> <property-name> (<struct name>)
+ * i.e. X Location (Bone1), or X Location (Object)
+ *
+ * Currently, option 2 is in use, to try and make it easier to quickly identify F-Curves (it does have
+ * problems with looking rather odd though). Option 1 is better in terms of revealing a consistent sense of
+ * hierarchy though, which isn't so clear with option 2.
+ */
+
+ /* for structname
+ * - as base, we use a custom name from the structs if one is available
+ * - however, if we're showing subdata of bones (probably there will be other exceptions later)
+ * need to include that info too since it gets confusing otherwise
+ * - if a pointer just refers to the ID-block, then don't repeat this info
+ * since this just introduces clutter
+ */
+ if (strstr(fcu->rna_path, "bones") && strstr(fcu->rna_path, "constraints")) {
+ /* perform string 'chopping' to get "Bone Name : Constraint Name" */
+ char *pchanName = BLI_str_quoted_substrN(fcu->rna_path, "bones[");
+ char *constName = BLI_str_quoted_substrN(fcu->rna_path, "constraints[");
+
+ /* assemble the string to display in the UI... */
+ structname = BLI_sprintfN("%s : %s", pchanName, constName);
+ free_structname = 1;
+
+ /* free the temp names */
+ if (pchanName)
+ MEM_freeN(pchanName);
+ if (constName)
+ MEM_freeN(constName);
+ }
+ else if (ptr.data != ptr.id.data) {
+ PropertyRNA *nameprop = RNA_struct_name_property(ptr.type);
+ if (nameprop) {
+ /* this gets a string which will need to be freed */
+ structname = RNA_property_string_get_alloc(&ptr, nameprop, NULL, 0, NULL);
+ free_structname = 1;
+ }
+ else
+ structname = RNA_struct_ui_name(ptr.type);
+ }
+
+ /* Property Name is straightforward */
+ propname = RNA_property_ui_name(prop);
+
+ /* Array Index - only if applicable */
+ if (RNA_property_array_check(prop)) {
+ char c = RNA_property_array_item_char(prop, fcu->array_index);
+
+ /* we need to write the index to a temp buffer (in py syntax) */
+ if (c)
+ BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "%c ", c);
+ else
+ BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "[%d]", fcu->array_index);
+
+ arrayname = &arrayindbuf[0];
+ }
+ else {
+ /* no array index */
+ arrayname = "";
+ }
+
+ /* putting this all together into the buffer */
+ /* XXX we need to check for invalid names...
+ * XXX the name length limit needs to be passed in or as some define */
+ if (structname)
+ BLI_snprintf(name, 256, "%s%s (%s)", arrayname, propname, structname);
+ else
+ BLI_snprintf(name, 256, "%s%s", arrayname, propname);
+
+ /* free temp name if nameprop is set */
+ if (free_structname)
+ MEM_freeN((void *)structname);
+
+ /* Icon for this property's owner:
+ * use the struct's icon if it is set
+ */
+ icon = RNA_struct_ui_icon(ptr.type);
+
+ /* valid path - remove the invalid tag since we now know how to use it saving
+ * users manual effort to reenable using "Revive Disabled FCurves" [#29629]
+ */
+ fcu->flag &= ~FCURVE_DISABLED;
+ }
+ else {
+ /* invalid path */
+ BLI_snprintf(name, 256, "\"%s[%d]\"", fcu->rna_path, fcu->array_index);
+
+ /* icon for this should be the icon for the base ID */
+ /* TODO: or should we just use the error icon? */
+ icon = RNA_struct_ui_icon(id_ptr.type);
+
+ /* tag F-Curve as disabled - as not usable path */
+ fcu->flag |= FCURVE_DISABLED;
+ }
+ }
+
+ /* return the icon that the active data had */
+ return icon;
}
/* ------------------------------- Color Codes for F-Curve Channels ---------------------------- */
/* step between the major distinguishable color bands of the primary colors */
-#define HSV_BANDWIDTH 0.3f
+#define HSV_BANDWIDTH 0.3f
/* used to determine the color of F-Curves with FCURVE_COLOR_AUTO_RAINBOW set */
// void fcurve_rainbow(unsigned int cur, unsigned int tot, float *out)
void getcolor_fcurve_rainbow(int cur, int tot, float out[3])
{
- float hsv[3], fac;
- int grouping;
-
- /* we try to divide the color into groupings of n colors,
- * where n is:
- * 3 - for 'odd' numbers of curves - there should be a majority of triplets of curves
- * 4 - for 'even' numbers of curves - there should be a majority of quartets of curves
- * so the base color is simply one of the three primary colors
- */
- grouping = (4 - (tot % 2));
- hsv[0] = HSV_BANDWIDTH * (float)(cur % grouping);
-
- /* 'Value' (i.e. darkness) needs to vary so that larger sets of three will be
- * 'darker' (i.e. smaller value), so that they don't look that similar to previous ones.
- * However, only a range of 0.3 to 1.0 is really usable to avoid clashing
- * with some other stuff
- */
- fac = ((float)cur / (float)tot) * 0.7f;
-
- /* the base color can get offset a bit so that the colors aren't so identical */
- hsv[0] += fac * HSV_BANDWIDTH;
- if (hsv[0] > 1.0f) hsv[0] = fmod(hsv[0], 1.0f);
-
- /* saturation adjustments for more visible range */
- hsv[1] = ((hsv[0] > 0.5f) && (hsv[0] < 0.8f)) ? 0.5f : 0.6f;
-
- /* value is fixed at 1.0f, otherwise we cannot clearly see the curves... */
- hsv[2] = 1.0f;
-
- /* finally, conver this to RGB colors */
- hsv_to_rgb_v(hsv, out);
+ float hsv[3], fac;
+ int grouping;
+
+ /* we try to divide the color into groupings of n colors,
+ * where n is:
+ * 3 - for 'odd' numbers of curves - there should be a majority of triplets of curves
+ * 4 - for 'even' numbers of curves - there should be a majority of quartets of curves
+ * so the base color is simply one of the three primary colors
+ */
+ grouping = (4 - (tot % 2));
+ hsv[0] = HSV_BANDWIDTH * (float)(cur % grouping);
+
+ /* 'Value' (i.e. darkness) needs to vary so that larger sets of three will be
+ * 'darker' (i.e. smaller value), so that they don't look that similar to previous ones.
+ * However, only a range of 0.3 to 1.0 is really usable to avoid clashing
+ * with some other stuff
+ */
+ fac = ((float)cur / (float)tot) * 0.7f;
+
+ /* the base color can get offset a bit so that the colors aren't so identical */
+ hsv[0] += fac * HSV_BANDWIDTH;
+ if (hsv[0] > 1.0f)
+ hsv[0] = fmod(hsv[0], 1.0f);
+
+ /* saturation adjustments for more visible range */
+ hsv[1] = ((hsv[0] > 0.5f) && (hsv[0] < 0.8f)) ? 0.5f : 0.6f;
+
+ /* value is fixed at 1.0f, otherwise we cannot clearly see the curves... */
+ hsv[2] = 1.0f;
+
+ /* finally, conver this to RGB colors */
+ hsv_to_rgb_v(hsv, out);
}
diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c
index 7a9bb1df477..beffa47b2c5 100644
--- a/source/blender/editors/animation/anim_markers.c
+++ b/source/blender/editors/animation/anim_markers.c
@@ -76,24 +76,24 @@
/* helper function for getting the list of markers to work on */
static ListBase *context_get_markers(Scene *scene, ScrArea *sa)
{
- /* local marker sets... */
- if (sa) {
- if (sa->spacetype == SPACE_ACTION) {
- SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
-
- /* local markers can only be shown when there's only a single active action to grab them from
- * - flag only takes effect when there's an action, otherwise it can get too confusing?
- */
- if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY) && (saction->action)) {
- if (saction->flag & SACTION_POSEMARKERS_SHOW) {
- return &saction->action->markers;
- }
- }
- }
- }
-
- /* default to using the scene's markers */
- return &scene->markers;
+ /* local marker sets... */
+ if (sa) {
+ if (sa->spacetype == SPACE_ACTION) {
+ SpaceAction *saction = (SpaceAction *)sa->spacedata.first;
+
+ /* local markers can only be shown when there's only a single active action to grab them from
+ * - flag only takes effect when there's an action, otherwise it can get too confusing?
+ */
+ if (ELEM(saction->mode, SACTCONT_ACTION, SACTCONT_SHAPEKEY) && (saction->action)) {
+ if (saction->flag & SACTION_POSEMARKERS_SHOW) {
+ return &saction->action->markers;
+ }
+ }
+ }
+ }
+
+ /* default to using the scene's markers */
+ return &scene->markers;
}
/* ............. */
@@ -101,16 +101,16 @@ static ListBase *context_get_markers(Scene *scene, ScrArea *sa)
/* public API for getting markers from context */
ListBase *ED_context_get_markers(const bContext *C)
{
- return context_get_markers(CTX_data_scene(C), CTX_wm_area(C));
+ return context_get_markers(CTX_data_scene(C), CTX_wm_area(C));
}
/* public API for getting markers from "animation" context */
ListBase *ED_animcontext_get_markers(const bAnimContext *ac)
{
- if (ac)
- return context_get_markers(ac->scene, ac->sa);
- else
- return NULL;
+ if (ac)
+ return context_get_markers(ac->scene, ac->sa);
+ else
+ return NULL;
}
/* --------------------------------- */
@@ -125,48 +125,43 @@ ListBase *ED_animcontext_get_markers(const bAnimContext *ac)
* (which is delta transform for grab/extend, and scale factor for scale)
* \param side: (B/L/R) for 'extend' functionality, which side of current frame to use
*/
-int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, float value, char side)
+int ED_markers_post_apply_transform(
+ ListBase *markers, Scene *scene, int mode, float value, char side)
{
- TimeMarker *marker;
- float cfra = (float)CFRA;
- int changed_tot = 0;
-
- /* sanity check - no markers, or locked markers */
- if ((scene->toolsettings->lock_markers) ||
- (markers == NULL))
- {
- return changed_tot;
- }
-
- /* affect selected markers - it's unlikely that we will want to affect all in this way? */
- for (marker = markers->first; marker; marker = marker->next) {
- if (marker->flag & SELECT) {
- switch (mode) {
- case TFM_TIME_TRANSLATE:
- case TFM_TIME_EXTEND:
- {
- /* apply delta if marker is on the right side of the current frame */
- if ((side == 'B') ||
- (side == 'L' && marker->frame < cfra) ||
- (side == 'R' && marker->frame >= cfra))
- {
- marker->frame += round_fl_to_int(value);
- changed_tot++;
- }
- break;
- }
- case TFM_TIME_SCALE:
- {
- /* rescale the distance between the marker and the current frame */
- marker->frame = cfra + round_fl_to_int((float)(marker->frame - cfra) * value);
- changed_tot++;
- break;
- }
- }
- }
- }
-
- return changed_tot;
+ TimeMarker *marker;
+ float cfra = (float)CFRA;
+ int changed_tot = 0;
+
+ /* sanity check - no markers, or locked markers */
+ if ((scene->toolsettings->lock_markers) || (markers == NULL)) {
+ return changed_tot;
+ }
+
+ /* affect selected markers - it's unlikely that we will want to affect all in this way? */
+ for (marker = markers->first; marker; marker = marker->next) {
+ if (marker->flag & SELECT) {
+ switch (mode) {
+ case TFM_TIME_TRANSLATE:
+ case TFM_TIME_EXTEND: {
+ /* apply delta if marker is on the right side of the current frame */
+ if ((side == 'B') || (side == 'L' && marker->frame < cfra) ||
+ (side == 'R' && marker->frame >= cfra)) {
+ marker->frame += round_fl_to_int(value);
+ changed_tot++;
+ }
+ break;
+ }
+ case TFM_TIME_SCALE: {
+ /* rescale the distance between the marker and the current frame */
+ marker->frame = cfra + round_fl_to_int((float)(marker->frame - cfra) * value);
+ changed_tot++;
+ break;
+ }
+ }
+ }
+ }
+
+ return changed_tot;
}
/* --------------------------------- */
@@ -175,58 +170,57 @@ int ED_markers_post_apply_transform(ListBase *markers, Scene *scene, int mode, f
/* XXX for select, the min_dist should be small */
TimeMarker *ED_markers_find_nearest_marker(ListBase *markers, float x)
{
- TimeMarker *marker, *nearest = NULL;
- float dist, min_dist = 1000000;
+ TimeMarker *marker, *nearest = NULL;
+ float dist, min_dist = 1000000;
- if (markers) {
- for (marker = markers->first; marker; marker = marker->next) {
- dist = fabsf((float)marker->frame - x);
+ if (markers) {
+ for (marker = markers->first; marker; marker = marker->next) {
+ dist = fabsf((float)marker->frame - x);
- if (dist < min_dist) {
- min_dist = dist;
- nearest = marker;
- }
- }
- }
+ if (dist < min_dist) {
+ min_dist = dist;
+ nearest = marker;
+ }
+ }
+ }
- return nearest;
+ return nearest;
}
/* Return the time of the marker that occurs on a frame closest to the given time */
int ED_markers_find_nearest_marker_time(ListBase *markers, float x)
{
- TimeMarker *nearest = ED_markers_find_nearest_marker(markers, x);
- return (nearest) ? (nearest->frame) : round_fl_to_int(x);
+ TimeMarker *nearest = ED_markers_find_nearest_marker(markers, x);
+ return (nearest) ? (nearest->frame) : round_fl_to_int(x);
}
-
void ED_markers_get_minmax(ListBase *markers, short sel, float *first, float *last)
{
- TimeMarker *marker;
- float min, max;
-
- /* sanity check */
- //printf("markers = %p - %p, %p\n", markers, markers->first, markers->last);
- if (ELEM(NULL, markers, markers->first, markers->last)) {
- *first = 0.0f;
- *last = 0.0f;
- return;
- }
-
- min = FLT_MAX;
- max = -FLT_MAX;
- for (marker = markers->first; marker; marker = marker->next) {
- if (!sel || (marker->flag & SELECT)) {
- if (marker->frame < min)
- min = (float)marker->frame;
- if (marker->frame > max)
- max = (float)marker->frame;
- }
- }
-
- /* set the min/max values */
- *first = min;
- *last = max;
+ TimeMarker *marker;
+ float min, max;
+
+ /* sanity check */
+ //printf("markers = %p - %p, %p\n", markers, markers->first, markers->last);
+ if (ELEM(NULL, markers, markers->first, markers->last)) {
+ *first = 0.0f;
+ *last = 0.0f;
+ return;
+ }
+
+ min = FLT_MAX;
+ max = -FLT_MAX;
+ for (marker = markers->first; marker; marker = marker->next) {
+ if (!sel || (marker->flag & SELECT)) {
+ if (marker->frame < min)
+ min = (float)marker->frame;
+ if (marker->frame > max)
+ max = (float)marker->frame;
+ }
+ }
+
+ /* set the min/max values */
+ *first = min;
+ *last = max;
}
/* --------------------------------- */
@@ -234,31 +228,33 @@ void ED_markers_get_minmax(ListBase *markers, short sel, float *first, float *la
/* Adds a marker to list of cfra elems */
static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only_sel)
{
- CfraElem *ce, *cen;
-
- /* should this one only be considered if it is selected? */
- if ((only_sel) && ((marker->flag & SELECT) == 0))
- return;
-
- /* insertion sort - try to find a previous cfra elem */
- for (ce = lb->first; ce; ce = ce->next) {
- if (ce->cfra == marker->frame) {
- /* do because of double keys */
- if (marker->flag & SELECT)
- ce->sel = marker->flag;
- return;
- }
- else if (ce->cfra > marker->frame) {
- break;
- }
- }
-
- cen = MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem");
- if (ce) BLI_insertlinkbefore(lb, ce, cen);
- else BLI_addtail(lb, cen);
-
- cen->cfra = marker->frame;
- cen->sel = marker->flag;
+ CfraElem *ce, *cen;
+
+ /* should this one only be considered if it is selected? */
+ if ((only_sel) && ((marker->flag & SELECT) == 0))
+ return;
+
+ /* insertion sort - try to find a previous cfra elem */
+ for (ce = lb->first; ce; ce = ce->next) {
+ if (ce->cfra == marker->frame) {
+ /* do because of double keys */
+ if (marker->flag & SELECT)
+ ce->sel = marker->flag;
+ return;
+ }
+ else if (ce->cfra > marker->frame) {
+ break;
+ }
+ }
+
+ cen = MEM_callocN(sizeof(CfraElem), "add_to_cfra_elem");
+ if (ce)
+ BLI_insertlinkbefore(lb, ce, cen);
+ else
+ BLI_addtail(lb, cen);
+
+ cen->cfra = marker->frame;
+ cen->sel = marker->flag;
}
/* This function makes a list of all the markers. The only_sel
@@ -267,47 +263,47 @@ static void add_marker_to_cfra_elem(ListBase *lb, TimeMarker *marker, short only
*/
void ED_markers_make_cfra_list(ListBase *markers, ListBase *lb, short only_sel)
{
- TimeMarker *marker;
-
- if (lb) {
- /* Clear the list first, since callers have no way of knowing
- * whether this terminated early otherwise. This may lead
- * to crashes if the user didn't clear the memory first.
- */
- lb->first = lb->last = NULL;
- }
- else {
- return;
- }
-
- if (markers == NULL) {
- return;
- }
-
- for (marker = markers->first; marker; marker = marker->next)
- add_marker_to_cfra_elem(lb, marker, only_sel);
+ TimeMarker *marker;
+
+ if (lb) {
+ /* Clear the list first, since callers have no way of knowing
+ * whether this terminated early otherwise. This may lead
+ * to crashes if the user didn't clear the memory first.
+ */
+ lb->first = lb->last = NULL;
+ }
+ else {
+ return;
+ }
+
+ if (markers == NULL) {
+ return;
+ }
+
+ for (marker = markers->first; marker; marker = marker->next)
+ add_marker_to_cfra_elem(lb, marker, only_sel);
}
void ED_markers_deselect_all(ListBase *markers, int action)
{
- if (action == SEL_TOGGLE) {
- action = ED_markers_get_first_selected(markers) ? SEL_DESELECT : SEL_SELECT;
- }
-
- for (TimeMarker *marker = markers->first; marker; marker = marker->next) {
- if (action == SEL_SELECT) {
- marker->flag |= SELECT;
- }
- else if (action == SEL_DESELECT) {
- marker->flag &= ~SELECT;
- }
- else if (action == SEL_INVERT) {
- marker->flag ^= SELECT;
- }
- else {
- BLI_assert(0);
- }
- }
+ if (action == SEL_TOGGLE) {
+ action = ED_markers_get_first_selected(markers) ? SEL_DESELECT : SEL_SELECT;
+ }
+
+ for (TimeMarker *marker = markers->first; marker; marker = marker->next) {
+ if (action == SEL_SELECT) {
+ marker->flag |= SELECT;
+ }
+ else if (action == SEL_DESELECT) {
+ marker->flag &= ~SELECT;
+ }
+ else if (action == SEL_INVERT) {
+ marker->flag ^= SELECT;
+ }
+ else {
+ BLI_assert(0);
+ }
+ }
}
/* --------------------------------- */
@@ -315,16 +311,16 @@ void ED_markers_deselect_all(ListBase *markers, int action)
/* Get the first selected marker */
TimeMarker *ED_markers_get_first_selected(ListBase *markers)
{
- TimeMarker *marker;
+ TimeMarker *marker;
- if (markers) {
- for (marker = markers->first; marker; marker = marker->next) {
- if (marker->flag & SELECT)
- return marker;
- }
- }
+ if (markers) {
+ for (marker = markers->first; marker; marker = marker->next) {
+ if (marker->flag & SELECT)
+ return marker;
+ }
+ }
- return NULL;
+ return NULL;
}
/* --------------------------------- */
@@ -334,226 +330,229 @@ TimeMarker *ED_markers_get_first_selected(ListBase *markers)
*/
void debug_markers_print_list(ListBase *markers)
{
- TimeMarker *marker;
+ TimeMarker *marker;
- if (markers == NULL) {
- printf("No markers list to print debug for\n");
- return;
- }
+ if (markers == NULL) {
+ printf("No markers list to print debug for\n");
+ return;
+ }
- printf("List of markers follows: -----\n");
+ printf("List of markers follows: -----\n");
- for (marker = markers->first; marker; marker = marker->next) {
- printf("\t'%s' on %d at %p with %u\n", marker->name, marker->frame, (void *)marker, marker->flag);
- }
+ for (marker = markers->first; marker; marker = marker->next) {
+ printf(
+ "\t'%s' on %d at %p with %u\n", marker->name, marker->frame, (void *)marker, marker->flag);
+ }
- printf("End of list ------------------\n");
+ printf("End of list ------------------\n");
}
/* ************* Marker Drawing ************ */
-static void draw_marker_name(
- const uiFontStyle *fstyle, TimeMarker *marker, const char *name,
- int cfra, const float xpos, const float ypixels)
+static void draw_marker_name(const uiFontStyle *fstyle,
+ TimeMarker *marker,
+ const char *name,
+ int cfra,
+ const float xpos,
+ const float ypixels)
{
- unsigned char text_col[4];
- float x, y;
-
- /* minimal y coordinate which wouldn't be occluded by scroll */
- int min_y = 17.0f * UI_DPI_FAC;
-
- if (marker->flag & SELECT) {
- UI_GetThemeColor4ubv(TH_TEXT_HI, text_col);
- x = xpos + 4.0f * UI_DPI_FAC;
- y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC;
- y = max_ii(y, min_y);
- }
- else {
- UI_GetThemeColor4ubv(TH_TEXT, text_col);
- if ((marker->frame <= cfra) && (marker->frame + 5 > cfra)) {
- x = xpos + 8.0f * UI_DPI_FAC;
- y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC;
- y = max_ii(y, min_y);
- }
- else {
- x = xpos + 8.0f * UI_DPI_FAC;
- y = 17.0f * UI_DPI_FAC;
- }
- }
+ unsigned char text_col[4];
+ float x, y;
+
+ /* minimal y coordinate which wouldn't be occluded by scroll */
+ int min_y = 17.0f * UI_DPI_FAC;
+
+ if (marker->flag & SELECT) {
+ UI_GetThemeColor4ubv(TH_TEXT_HI, text_col);
+ x = xpos + 4.0f * UI_DPI_FAC;
+ y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC;
+ y = max_ii(y, min_y);
+ }
+ else {
+ UI_GetThemeColor4ubv(TH_TEXT, text_col);
+ if ((marker->frame <= cfra) && (marker->frame + 5 > cfra)) {
+ x = xpos + 8.0f * UI_DPI_FAC;
+ y = (ypixels <= 39.0f * UI_DPI_FAC) ? (ypixels - 10.0f * UI_DPI_FAC) : 29.0f * UI_DPI_FAC;
+ y = max_ii(y, min_y);
+ }
+ else {
+ x = xpos + 8.0f * UI_DPI_FAC;
+ y = 17.0f * UI_DPI_FAC;
+ }
+ }
#ifdef DURIAN_CAMERA_SWITCH
- if (marker->camera && (marker->camera->restrictflag & OB_RESTRICT_RENDER)) {
- text_col[3] = 100;
- }
+ if (marker->camera && (marker->camera->restrictflag & OB_RESTRICT_RENDER)) {
+ text_col[3] = 100;
+ }
#endif
- UI_fontstyle_draw_simple(fstyle, x, y, name, text_col);
+ UI_fontstyle_draw_simple(fstyle, x, y, name, text_col);
}
static void draw_marker_line(const float color[4], float x, float ymin, float ymax)
{
- GPUVertFormat *format = immVertexFormat();
- uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ GPUVertFormat *format = immVertexFormat();
+ uint pos = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
+ immBindBuiltinProgram(GPU_SHADER_2D_LINE_DASHED_UNIFORM_COLOR);
- float viewport_size[4];
- GPU_viewport_size_get_f(viewport_size);
- immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
+ float viewport_size[4];
+ GPU_viewport_size_get_f(viewport_size);
+ immUniform2f("viewport_size", viewport_size[2] / UI_DPI_FAC, viewport_size[3] / UI_DPI_FAC);
- immUniformColor4fv(color);
- immUniform1i("colors_len", 0); /* "simple" mode */
- immUniform1f("dash_width", 6.0f);
- immUniform1f("dash_factor", 0.5f);
+ immUniformColor4fv(color);
+ immUniform1i("colors_len", 0); /* "simple" mode */
+ immUniform1f("dash_width", 6.0f);
+ immUniform1f("dash_factor", 0.5f);
- immBegin(GPU_PRIM_LINES, 2);
- immVertex2f(pos, x, ymin);
- immVertex2f(pos, x, ymax);
- immEnd();
+ immBegin(GPU_PRIM_LINES, 2);
+ immVertex2f(pos, x, ymin);
+ immVertex2f(pos, x, ymax);
+ immEnd();
- immUnbindProgram();
+ immUnbindProgram();
}
/* function to draw markers */
-static void draw_marker(
- const uiFontStyle *fstyle, TimeMarker *marker, int cfra, int flag,
- /* avoid re-calculating each time */
- const float ypixels, const float xscale, int height)
+static void draw_marker(const uiFontStyle *fstyle,
+ TimeMarker *marker,
+ int cfra,
+ int flag,
+ /* avoid re-calculating each time */
+ const float ypixels,
+ const float xscale,
+ int height)
{
- const float xpos = marker->frame * xscale;
+ const float xpos = marker->frame * xscale;
#ifdef DURIAN_CAMERA_SWITCH
- const float yoffs = (marker->camera) ? 0.2f * UI_DPI_ICON_SIZE : 0.0f;
+ const float yoffs = (marker->camera) ? 0.2f * UI_DPI_ICON_SIZE : 0.0f;
#else
- const float yoffs = 0.0f;
+ const float yoffs = 0.0f;
#endif
- int icon_id;
+ int icon_id;
- GPU_blend(true);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
- /* vertical line - dotted */
+ /* vertical line - dotted */
#ifdef DURIAN_CAMERA_SWITCH
- if ((marker->camera) || (flag & DRAW_MARKERS_LINES))
+ if ((marker->camera) || (flag & DRAW_MARKERS_LINES))
#else
- if (flag & DRAW_MARKERS_LINES)
+ if (flag & DRAW_MARKERS_LINES)
#endif
- {
- float color[4];
- if (marker->flag & SELECT) {
- copy_v4_fl4(color, 1.0f, 1.0f, 1.0f, 0.38f);
- }
- else {
- copy_v4_fl4(color, 0.0f, 0.0f, 0.0f, 0.38f);
- }
-
- draw_marker_line(color, xpos, yoffs + 1.5f * UI_DPI_ICON_SIZE, height);
- }
-
- /* 5 px to offset icon to align properly, space / pixels corrects for zoom */
- if (flag & DRAW_MARKERS_LOCAL) {
- icon_id = (marker->flag & ACTIVE) ? ICON_PMARKER_ACT :
- (marker->flag & SELECT) ? ICON_PMARKER_SEL :
- ICON_PMARKER;
- }
+ {
+ float color[4];
+ if (marker->flag & SELECT) {
+ copy_v4_fl4(color, 1.0f, 1.0f, 1.0f, 0.38f);
+ }
+ else {
+ copy_v4_fl4(color, 0.0f, 0.0f, 0.0f, 0.38f);
+ }
+
+ draw_marker_line(color, xpos, yoffs + 1.5f * UI_DPI_ICON_SIZE, height);
+ }
+
+ /* 5 px to offset icon to align properly, space / pixels corrects for zoom */
+ if (flag & DRAW_MARKERS_LOCAL) {
+ icon_id = (marker->flag & ACTIVE) ? ICON_PMARKER_ACT :
+ (marker->flag & SELECT) ? ICON_PMARKER_SEL : ICON_PMARKER;
+ }
#ifdef DURIAN_CAMERA_SWITCH
- else if (marker->camera) {
- icon_id = (marker->flag & SELECT) ? ICON_OUTLINER_OB_CAMERA :
- ICON_CAMERA_DATA;
- }
+ else if (marker->camera) {
+ icon_id = (marker->flag & SELECT) ? ICON_OUTLINER_OB_CAMERA : ICON_CAMERA_DATA;
+ }
#endif
- else {
- icon_id = (marker->flag & SELECT) ? ICON_MARKER_HLT :
- ICON_MARKER;
- }
+ else {
+ icon_id = (marker->flag & SELECT) ? ICON_MARKER_HLT : ICON_MARKER;
+ }
- UI_icon_draw(xpos - 0.55f * UI_DPI_ICON_SIZE, yoffs + UI_DPI_ICON_SIZE, icon_id);
+ UI_icon_draw(xpos - 0.55f * UI_DPI_ICON_SIZE, yoffs + UI_DPI_ICON_SIZE, icon_id);
- GPU_blend(false);
+ GPU_blend(false);
- /* and the marker name too, shifted slightly to the top-right */
+ /* and the marker name too, shifted slightly to the top-right */
#ifdef DURIAN_CAMERA_SWITCH
- if (marker->camera) {
- draw_marker_name(fstyle, marker, marker->camera->id.name + 2, cfra, xpos, ypixels);
- }
- else if (marker->name[0]) {
- draw_marker_name(fstyle, marker, marker->name, cfra, xpos, ypixels);
- }
+ if (marker->camera) {
+ draw_marker_name(fstyle, marker, marker->camera->id.name + 2, cfra, xpos, ypixels);
+ }
+ else if (marker->name[0]) {
+ draw_marker_name(fstyle, marker, marker->name, cfra, xpos, ypixels);
+ }
#else
- if (marker->name[0]) {
- draw_marker_name(fstyle, marker, marker->name, cfra, xpos, ypixels);
-
- }
+ if (marker->name[0]) {
+ draw_marker_name(fstyle, marker, marker->name, cfra, xpos, ypixels);
+ }
#endif
}
/* Draw Scene-Markers in time window */
void ED_markers_draw(const bContext *C, int flag)
{
- const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- ListBase *markers = ED_context_get_markers(C);
- View2D *v2d;
- TimeMarker *marker;
- Scene *scene;
- int select_pass;
- int v2d_clip_range_x[2];
- float font_width_max;
-
- /* cache values */
- float ypixels, xscale, yscale;
-
- if (markers == NULL || BLI_listbase_is_empty(markers)) {
- return;
- }
-
- scene = CTX_data_scene(C);
- v2d = UI_view2d_fromcontext(C);
- int height = v2d->mask.ymax - v2d->mask.ymin;
-
- if (flag & DRAW_MARKERS_MARGIN) {
- uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
-
- const unsigned char shade[4] = {0, 0, 0, 16};
- immUniformColor4ubv(shade);
-
- GPU_blend(true);
- GPU_blend_set_func_separate(GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
-
- immRectf(pos, v2d->cur.xmin, 0, v2d->cur.xmax, UI_MARKER_MARGIN_Y);
-
- GPU_blend(false);
-
- immUnbindProgram();
- }
-
- /* no time correction for framelen! space is drawn with old values */
- ypixels = BLI_rcti_size_y(&v2d->mask);
- UI_view2d_scale_get(v2d, &xscale, &yscale);
- GPU_matrix_push();
- GPU_matrix_scale_2f(1.0f / xscale, 1.0f);
-
- /* x-bounds with offset for text (adjust for long string, avoid checking string width) */
- font_width_max = (10 * UI_DPI_FAC) / xscale;
- v2d_clip_range_x[0] = v2d->cur.xmin - (sizeof(marker->name) * font_width_max);
- v2d_clip_range_x[1] = v2d->cur.xmax + font_width_max;
-
- /* loop [unselected, selected] */
- for (select_pass = 0; select_pass <= SELECT; select_pass += SELECT) {
- /* unselected markers are drawn at the first time */
- for (marker = markers->first; marker; marker = marker->next) {
- if ((marker->flag & SELECT) == select_pass) {
- /* bounds check */
- if ((marker->frame >= v2d_clip_range_x[0]) &&
- (marker->frame <= v2d_clip_range_x[1]))
- {
- draw_marker(fstyle, marker, scene->r.cfra, flag,
- ypixels, xscale, height);
- }
- }
- }
- }
-
- GPU_matrix_pop();
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ ListBase *markers = ED_context_get_markers(C);
+ View2D *v2d;
+ TimeMarker *marker;
+ Scene *scene;
+ int select_pass;
+ int v2d_clip_range_x[2];
+ float font_width_max;
+
+ /* cache values */
+ float ypixels, xscale, yscale;
+
+ if (markers == NULL || BLI_listbase_is_empty(markers)) {
+ return;
+ }
+
+ scene = CTX_data_scene(C);
+ v2d = UI_view2d_fromcontext(C);
+ int height = v2d->mask.ymax - v2d->mask.ymin;
+
+ if (flag & DRAW_MARKERS_MARGIN) {
+ uint pos = GPU_vertformat_attr_add(immVertexFormat(), "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_UNIFORM_COLOR);
+
+ const unsigned char shade[4] = {0, 0, 0, 16};
+ immUniformColor4ubv(shade);
+
+ GPU_blend(true);
+ GPU_blend_set_func_separate(
+ GPU_SRC_ALPHA, GPU_ONE_MINUS_SRC_ALPHA, GPU_ONE, GPU_ONE_MINUS_SRC_ALPHA);
+
+ immRectf(pos, v2d->cur.xmin, 0, v2d->cur.xmax, UI_MARKER_MARGIN_Y);
+
+ GPU_blend(false);
+
+ immUnbindProgram();
+ }
+
+ /* no time correction for framelen! space is drawn with old values */
+ ypixels = BLI_rcti_size_y(&v2d->mask);
+ UI_view2d_scale_get(v2d, &xscale, &yscale);
+ GPU_matrix_push();
+ GPU_matrix_scale_2f(1.0f / xscale, 1.0f);
+
+ /* x-bounds with offset for text (adjust for long string, avoid checking string width) */
+ font_width_max = (10 * UI_DPI_FAC) / xscale;
+ v2d_clip_range_x[0] = v2d->cur.xmin - (sizeof(marker->name) * font_width_max);
+ v2d_clip_range_x[1] = v2d->cur.xmax + font_width_max;
+
+ /* loop [unselected, selected] */
+ for (select_pass = 0; select_pass <= SELECT; select_pass += SELECT) {
+ /* unselected markers are drawn at the first time */
+ for (marker = markers->first; marker; marker = marker->next) {
+ if ((marker->flag & SELECT) == select_pass) {
+ /* bounds check */
+ if ((marker->frame >= v2d_clip_range_x[0]) && (marker->frame <= v2d_clip_range_x[1])) {
+ draw_marker(fstyle, marker, scene->r.cfra, flag, ypixels, xscale, height);
+ }
+ }
+ }
+ }
+
+ GPU_matrix_pop();
}
/* ************************ Marker Wrappers API ********************* */
@@ -567,48 +566,47 @@ void ED_markers_draw(const bContext *C, int flag)
/* special poll() which checks if there are selected markers first */
static bool ed_markers_poll_selected_markers(bContext *C)
{
- ListBase *markers = ED_context_get_markers(C);
+ ListBase *markers = ED_context_get_markers(C);
- /* first things first: markers can only exist in timeline views */
- if (ED_operator_animview_active(C) == 0)
- return 0;
+ /* first things first: markers can only exist in timeline views */
+ if (ED_operator_animview_active(C) == 0)
+ return 0;
- /* check if some marker is selected */
- return ED_markers_get_first_selected(markers) != NULL;
+ /* check if some marker is selected */
+ return ED_markers_get_first_selected(markers) != NULL;
}
static bool ed_markers_poll_selected_no_locked_markers(bContext *C)
{
- ListBase *markers = ED_context_get_markers(C);
- ToolSettings *ts = CTX_data_tool_settings(C);
+ ListBase *markers = ED_context_get_markers(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
- if (ts->lock_markers)
- return 0;
+ if (ts->lock_markers)
+ return 0;
- /* first things first: markers can only exist in timeline views */
- if (ED_operator_animview_active(C) == 0)
- return 0;
+ /* first things first: markers can only exist in timeline views */
+ if (ED_operator_animview_active(C) == 0)
+ return 0;
- /* check if some marker is selected */
- return ED_markers_get_first_selected(markers) != NULL;
+ /* check if some marker is selected */
+ return ED_markers_get_first_selected(markers) != NULL;
}
-
/* special poll() which checks if there are any markers at all first */
static bool ed_markers_poll_markers_exist(bContext *C)
{
- ListBase *markers = ED_context_get_markers(C);
- ToolSettings *ts = CTX_data_tool_settings(C);
+ ListBase *markers = ED_context_get_markers(C);
+ ToolSettings *ts = CTX_data_tool_settings(C);
- if (ts->lock_markers)
- return 0;
+ if (ts->lock_markers)
+ return 0;
- /* first things first: markers can only exist in timeline views */
- if (ED_operator_animview_active(C) == 0)
- return 0;
+ /* first things first: markers can only exist in timeline views */
+ if (ED_operator_animview_active(C) == 0)
+ return 0;
- /* list of markers must exist, as well as some markers in it! */
- return (markers && markers->first);
+ /* list of markers must exist, as well as some markers in it! */
+ return (markers && markers->first);
}
/* ------------------------ */
@@ -622,29 +620,34 @@ static bool ed_markers_poll_markers_exist(bContext *C)
* If NULL, the operator's standard exec()
* callback will be called instead in the appropriate places.
*/
-static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, const wmEvent *event,
- int (*invoke_func)(bContext *, wmOperator *, const wmEvent *))
+static int ed_markers_opwrap_invoke_custom(bContext *C,
+ wmOperator *op,
+ const wmEvent *event,
+ int (*invoke_func)(bContext *,
+ wmOperator *,
+ const wmEvent *))
{
- int retval = OPERATOR_PASS_THROUGH;
-
- /* removed check for Y coord of event, keymap has bounbox now */
-
- /* allow operator to run now */
- if (invoke_func)
- retval = invoke_func(C, op, event);
- else if (op->type->exec)
- retval = op->type->exec(C, op);
- else
- BKE_report(op->reports, RPT_ERROR, "Programming error: operator does not actually have code to do anything!");
-
-
- /* unless successful, must add "pass-through"
- * to let normal operator's have a chance at tackling this event */
- if ((retval & (OPERATOR_FINISHED | OPERATOR_INTERFACE)) == 0) {
- retval |= OPERATOR_PASS_THROUGH;
- }
-
- return retval;
+ int retval = OPERATOR_PASS_THROUGH;
+
+ /* removed check for Y coord of event, keymap has bounbox now */
+
+ /* allow operator to run now */
+ if (invoke_func)
+ retval = invoke_func(C, op, event);
+ else if (op->type->exec)
+ retval = op->type->exec(C, op);
+ else
+ BKE_report(op->reports,
+ RPT_ERROR,
+ "Programming error: operator does not actually have code to do anything!");
+
+ /* unless successful, must add "pass-through"
+ * to let normal operator's have a chance at tackling this event */
+ if ((retval & (OPERATOR_FINISHED | OPERATOR_INTERFACE)) == 0) {
+ retval |= OPERATOR_PASS_THROUGH;
+ }
+
+ return retval;
}
/* standard wrapper - first-tier invoke() callback to be directly assigned to operator typedata
@@ -654,7 +657,7 @@ static int ed_markers_opwrap_invoke_custom(bContext *C, wmOperator *op, const wm
*/
static int ed_markers_opwrap_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, event, NULL);
+ return ed_markers_opwrap_invoke_custom(C, op, event, NULL);
}
/* ************************** add markers *************************** */
@@ -662,50 +665,50 @@ static int ed_markers_opwrap_invoke(bContext *C, wmOperator *op, const wmEvent *
/* add TimeMarker at current frame */
static int ed_marker_add_exec(bContext *C, wmOperator *UNUSED(op))
{
- ListBase *markers = ED_context_get_markers(C);
- TimeMarker *marker;
- int frame = CTX_data_scene(C)->r.cfra;
-
- if (markers == NULL)
- return OPERATOR_CANCELLED;
-
- /* prefer not having 2 markers at the same place,
- * though the user can move them to overlap once added */
- for (marker = markers->first; marker; marker = marker->next) {
- if (marker->frame == frame)
- return OPERATOR_CANCELLED;
- }
-
- /* deselect all */
- for (marker = markers->first; marker; marker = marker->next)
- marker->flag &= ~SELECT;
-
- marker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
- marker->flag = SELECT;
- marker->frame = frame;
- BLI_snprintf(marker->name, sizeof(marker->name), "F_%02d", frame); // XXX - temp code only
- BLI_addtail(markers, marker);
-
- WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
-
- return OPERATOR_FINISHED;
+ ListBase *markers = ED_context_get_markers(C);
+ TimeMarker *marker;
+ int frame = CTX_data_scene(C)->r.cfra;
+
+ if (markers == NULL)
+ return OPERATOR_CANCELLED;
+
+ /* prefer not having 2 markers at the same place,
+ * though the user can move them to overlap once added */
+ for (marker = markers->first; marker; marker = marker->next) {
+ if (marker->frame == frame)
+ return OPERATOR_CANCELLED;
+ }
+
+ /* deselect all */
+ for (marker = markers->first; marker; marker = marker->next)
+ marker->flag &= ~SELECT;
+
+ marker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
+ marker->flag = SELECT;
+ marker->frame = frame;
+ BLI_snprintf(marker->name, sizeof(marker->name), "F_%02d", frame); // XXX - temp code only
+ BLI_addtail(markers, marker);
+
+ WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
+
+ return OPERATOR_FINISHED;
}
static void MARKER_OT_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Time Marker";
- ot->description = "Add a new time marker";
- ot->idname = "MARKER_OT_add";
-
- /* api callbacks */
- ot->exec = ed_marker_add_exec;
- ot->invoke = ed_markers_opwrap_invoke;
- ot->poll = ED_operator_animview_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* identifiers */
+ ot->name = "Add Time Marker";
+ ot->description = "Add a new time marker";
+ ot->idname = "MARKER_OT_add";
+
+ /* api callbacks */
+ ot->exec = ed_marker_add_exec;
+ ot->invoke = ed_markers_opwrap_invoke;
+ ot->poll = ED_operator_animview_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ************************** transform markers *************************** */
@@ -733,315 +736,323 @@ static void MARKER_OT_add(wmOperatorType *ot)
*/
typedef struct MarkerMove {
- SpaceLink *slink;
- ListBase *markers;
- int event_type; /* store invoke-event, to verify */
- int *oldframe, evtx, firstx;
- NumInput num;
+ SpaceLink *slink;
+ ListBase *markers;
+ int event_type; /* store invoke-event, to verify */
+ int *oldframe, evtx, firstx;
+ NumInput num;
} MarkerMove;
static bool ed_marker_move_use_time(MarkerMove *mm)
{
- if (((mm->slink->spacetype == SPACE_SEQ) && !(((SpaceSeq *)mm->slink)->flag & SEQ_DRAWFRAMES)) ||
- ((mm->slink->spacetype == SPACE_ACTION) && (((SpaceAction *)mm->slink)->flag & SACTION_DRAWTIME)) ||
- ((mm->slink->spacetype == SPACE_GRAPH) && !(((SpaceGraph *)mm->slink)->flag & SIPO_DRAWTIME)) ||
- ((mm->slink->spacetype == SPACE_NLA) && !(((SpaceNla *)mm->slink)->flag & SNLA_DRAWTIME)))
- {
- return true;
- }
-
- return false;
+ if (((mm->slink->spacetype == SPACE_SEQ) && !(((SpaceSeq *)mm->slink)->flag & SEQ_DRAWFRAMES)) ||
+ ((mm->slink->spacetype == SPACE_ACTION) &&
+ (((SpaceAction *)mm->slink)->flag & SACTION_DRAWTIME)) ||
+ ((mm->slink->spacetype == SPACE_GRAPH) &&
+ !(((SpaceGraph *)mm->slink)->flag & SIPO_DRAWTIME)) ||
+ ((mm->slink->spacetype == SPACE_NLA) && !(((SpaceNla *)mm->slink)->flag & SNLA_DRAWTIME))) {
+ return true;
+ }
+
+ return false;
}
static void ed_marker_move_update_header(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- MarkerMove *mm = op->customdata;
- TimeMarker *marker, *selmarker = NULL;
- const int offs = RNA_int_get(op->ptr, "frames");
- char str[UI_MAX_DRAW_STR];
- char str_offs[NUM_STR_REP_LEN];
- int totmark;
- const bool use_time = ed_marker_move_use_time(mm);
-
- for (totmark = 0, marker = mm->markers->first; marker; marker = marker->next) {
- if (marker->flag & SELECT) {
- selmarker = marker;
- totmark++;
- }
- }
-
- if (hasNumInput(&mm->num)) {
- outputNumInput(&mm->num, str_offs, &scene->unit);
- }
- else if (use_time) {
- BLI_snprintf(str_offs, sizeof(str_offs), "%.2f", FRA2TIME(offs));
- }
- else {
- BLI_snprintf(str_offs, sizeof(str_offs), "%d", offs);
- }
-
- if (totmark == 1 && selmarker) {
- /* we print current marker value */
- if (use_time) {
- BLI_snprintf(str, sizeof(str), IFACE_("Marker %.2f offset %s"), FRA2TIME(selmarker->frame), str_offs);
- }
- else {
- BLI_snprintf(str, sizeof(str), IFACE_("Marker %d offset %s"), selmarker->frame, str_offs);
- }
- }
- else {
- BLI_snprintf(str, sizeof(str), IFACE_("Marker offset %s"), str_offs);
- }
-
- ED_area_status_text(CTX_wm_area(C), str);
+ Scene *scene = CTX_data_scene(C);
+ MarkerMove *mm = op->customdata;
+ TimeMarker *marker, *selmarker = NULL;
+ const int offs = RNA_int_get(op->ptr, "frames");
+ char str[UI_MAX_DRAW_STR];
+ char str_offs[NUM_STR_REP_LEN];
+ int totmark;
+ const bool use_time = ed_marker_move_use_time(mm);
+
+ for (totmark = 0, marker = mm->markers->first; marker; marker = marker->next) {
+ if (marker->flag & SELECT) {
+ selmarker = marker;
+ totmark++;
+ }
+ }
+
+ if (hasNumInput(&mm->num)) {
+ outputNumInput(&mm->num, str_offs, &scene->unit);
+ }
+ else if (use_time) {
+ BLI_snprintf(str_offs, sizeof(str_offs), "%.2f", FRA2TIME(offs));
+ }
+ else {
+ BLI_snprintf(str_offs, sizeof(str_offs), "%d", offs);
+ }
+
+ if (totmark == 1 && selmarker) {
+ /* we print current marker value */
+ if (use_time) {
+ BLI_snprintf(
+ str, sizeof(str), IFACE_("Marker %.2f offset %s"), FRA2TIME(selmarker->frame), str_offs);
+ }
+ else {
+ BLI_snprintf(str, sizeof(str), IFACE_("Marker %d offset %s"), selmarker->frame, str_offs);
+ }
+ }
+ else {
+ BLI_snprintf(str, sizeof(str), IFACE_("Marker offset %s"), str_offs);
+ }
+
+ ED_area_status_text(CTX_wm_area(C), str);
}
/* copy selection to temp buffer */
/* return 0 if not OK */
static bool ed_marker_move_init(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- ListBase *markers = ED_context_get_markers(C);
- MarkerMove *mm;
- TimeMarker *marker;
- int a, totmark;
-
- if (markers == NULL) {
- return false;
- }
-
- for (totmark = 0, marker = markers->first; marker; marker = marker->next) {
- if (marker->flag & SELECT) {
- totmark++;
- }
- }
-
- if (totmark == 0) {
- return false;
- }
-
- op->customdata = mm = MEM_callocN(sizeof(MarkerMove), "Markermove");
- mm->slink = CTX_wm_space_data(C);
- mm->markers = markers;
- mm->oldframe = MEM_callocN(totmark * sizeof(int), "MarkerMove oldframe");
-
- initNumInput(&mm->num);
- mm->num.idx_max = 0; /* one axis */
- mm->num.val_flag[0] |= NUM_NO_FRACTION;
- mm->num.unit_sys = scene->unit.system;
- /* No time unit supporting frames currently... */
- mm->num.unit_type[0] = ed_marker_move_use_time(mm) ? B_UNIT_TIME : B_UNIT_NONE;
-
- for (a = 0, marker = markers->first; marker; marker = marker->next) {
- if (marker->flag & SELECT) {
- mm->oldframe[a] = marker->frame;
- a++;
- }
- }
-
- return true;
+ Scene *scene = CTX_data_scene(C);
+ ListBase *markers = ED_context_get_markers(C);
+ MarkerMove *mm;
+ TimeMarker *marker;
+ int a, totmark;
+
+ if (markers == NULL) {
+ return false;
+ }
+
+ for (totmark = 0, marker = markers->first; marker; marker = marker->next) {
+ if (marker->flag & SELECT) {
+ totmark++;
+ }
+ }
+
+ if (totmark == 0) {
+ return false;
+ }
+
+ op->customdata = mm = MEM_callocN(sizeof(MarkerMove), "Markermove");
+ mm->slink = CTX_wm_space_data(C);
+ mm->markers = markers;
+ mm->oldframe = MEM_callocN(totmark * sizeof(int), "MarkerMove oldframe");
+
+ initNumInput(&mm->num);
+ mm->num.idx_max = 0; /* one axis */
+ mm->num.val_flag[0] |= NUM_NO_FRACTION;
+ mm->num.unit_sys = scene->unit.system;
+ /* No time unit supporting frames currently... */
+ mm->num.unit_type[0] = ed_marker_move_use_time(mm) ? B_UNIT_TIME : B_UNIT_NONE;
+
+ for (a = 0, marker = markers->first; marker; marker = marker->next) {
+ if (marker->flag & SELECT) {
+ mm->oldframe[a] = marker->frame;
+ a++;
+ }
+ }
+
+ return true;
}
/* free stuff */
static void ed_marker_move_exit(bContext *C, wmOperator *op)
{
- MarkerMove *mm = op->customdata;
+ MarkerMove *mm = op->customdata;
- /* free data */
- MEM_freeN(mm->oldframe);
- MEM_freeN(op->customdata);
- op->customdata = NULL;
+ /* free data */
+ MEM_freeN(mm->oldframe);
+ MEM_freeN(op->customdata);
+ op->customdata = NULL;
- /* clear custom header prints */
- ED_area_status_text(CTX_wm_area(C), NULL);
+ /* clear custom header prints */
+ ED_area_status_text(CTX_wm_area(C), NULL);
}
static int ed_marker_move_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- if (ed_marker_move_init(C, op)) {
- MarkerMove *mm = op->customdata;
+ if (ed_marker_move_init(C, op)) {
+ MarkerMove *mm = op->customdata;
- mm->evtx = event->x;
- mm->firstx = event->x;
- mm->event_type = event->type;
+ mm->evtx = event->x;
+ mm->firstx = event->x;
+ mm->event_type = event->type;
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
- /* reset frs delta */
- RNA_int_set(op->ptr, "frames", 0);
+ /* reset frs delta */
+ RNA_int_set(op->ptr, "frames", 0);
- ed_marker_move_update_header(C, op);
+ ed_marker_move_update_header(C, op);
- return OPERATOR_RUNNING_MODAL;
- }
+ return OPERATOR_RUNNING_MODAL;
+ }
- return OPERATOR_CANCELLED;
+ return OPERATOR_CANCELLED;
}
static int ed_marker_move_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, event, ed_marker_move_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, ed_marker_move_invoke);
}
/* note, init has to be called successfully */
static void ed_marker_move_apply(bContext *C, wmOperator *op)
{
#ifdef DURIAN_CAMERA_SWITCH
- bScreen *sc = CTX_wm_screen(C);
- Scene *scene = CTX_data_scene(C);
- Object *camera = scene->camera;
+ bScreen *sc = CTX_wm_screen(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *camera = scene->camera;
#endif
- MarkerMove *mm = op->customdata;
- TimeMarker *marker;
- int a, offs;
+ MarkerMove *mm = op->customdata;
+ TimeMarker *marker;
+ int a, offs;
- offs = RNA_int_get(op->ptr, "frames");
- for (a = 0, marker = mm->markers->first; marker; marker = marker->next) {
- if (marker->flag & SELECT) {
- marker->frame = mm->oldframe[a] + offs;
- a++;
- }
- }
+ offs = RNA_int_get(op->ptr, "frames");
+ for (a = 0, marker = mm->markers->first; marker; marker = marker->next) {
+ if (marker->flag & SELECT) {
+ marker->frame = mm->oldframe[a] + offs;
+ a++;
+ }
+ }
- WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
#ifdef DURIAN_CAMERA_SWITCH
- /* so we get view3d redraws */
- BKE_scene_camera_switch_update(scene);
+ /* so we get view3d redraws */
+ BKE_scene_camera_switch_update(scene);
- if (camera != scene->camera) {
- BKE_screen_view3d_scene_sync(sc, scene);
- WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene);
- }
+ if (camera != scene->camera) {
+ BKE_screen_view3d_scene_sync(sc, scene);
+ WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene);
+ }
#endif
}
/* only for modal */
static void ed_marker_move_cancel(bContext *C, wmOperator *op)
{
- RNA_int_set(op->ptr, "frames", 0);
- ed_marker_move_apply(C, op);
- ed_marker_move_exit(C, op);
+ RNA_int_set(op->ptr, "frames", 0);
+ ed_marker_move_apply(C, op);
+ ed_marker_move_exit(C, op);
}
static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- Scene *scene = CTX_data_scene(C);
- MarkerMove *mm = op->customdata;
- View2D *v2d = UI_view2d_fromcontext(C);
- const bool has_numinput = hasNumInput(&mm->num);
- const bool use_time = ed_marker_move_use_time(mm);
-
- /* Modal numinput active, try to handle numeric inputs first... */
- if (event->val == KM_PRESS && has_numinput && handleNumInput(C, &mm->num, event)) {
- float value = (float)RNA_int_get(op->ptr, "frames");
-
- applyNumInput(&mm->num, &value);
- if (use_time) {
- value = TIME2FRA(value);
- }
-
- RNA_int_set(op->ptr, "frames", (int)value);
- ed_marker_move_apply(C, op);
- ed_marker_move_update_header(C, op);
- }
- else {
- bool handled = false;
- switch (event->type) {
- case ESCKEY:
- ed_marker_move_cancel(C, op);
- return OPERATOR_CANCELLED;
- case RIGHTMOUSE:
- /* press = user manually demands transform to be canceled */
- if (event->val == KM_PRESS) {
- ed_marker_move_cancel(C, op);
- return OPERATOR_CANCELLED;
- }
- /* else continue; <--- see if release event should be caught for tweak-end */
- ATTR_FALLTHROUGH;
-
- case RETKEY:
- case PADENTER:
- case LEFTMOUSE:
- case MIDDLEMOUSE:
- if (WM_event_is_modal_tweak_exit(event, mm->event_type)) {
- ed_marker_move_exit(C, op);
- WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
- return OPERATOR_FINISHED;
- }
- break;
- case MOUSEMOVE:
- if (!has_numinput) {
- float dx;
-
- dx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
-
- if (event->x != mm->evtx) { /* XXX maybe init for first time */
- float fac;
-
- mm->evtx = event->x;
- fac = ((float)(event->x - mm->firstx) * dx);
-
- apply_keyb_grid(event->shift, event->ctrl, &fac, 0.0, 1.0, 0.1, 0 /*was: U.flag & USER_AUTOGRABGRID*/);
-
- RNA_int_set(op->ptr, "frames", (int)fac);
- ed_marker_move_apply(C, op);
- ed_marker_move_update_header(C, op);
- }
- }
- break;
- }
-
- if (!handled && event->val == KM_PRESS && handleNumInput(C, &mm->num, event)) {
- float value = (float)RNA_int_get(op->ptr, "frames");
-
- applyNumInput(&mm->num, &value);
- if (use_time) {
- value = TIME2FRA(value);
- }
-
- RNA_int_set(op->ptr, "frames", (int)value);
- ed_marker_move_apply(C, op);
- ed_marker_move_update_header(C, op);
- }
- }
-
- return OPERATOR_RUNNING_MODAL;
+ Scene *scene = CTX_data_scene(C);
+ MarkerMove *mm = op->customdata;
+ View2D *v2d = UI_view2d_fromcontext(C);
+ const bool has_numinput = hasNumInput(&mm->num);
+ const bool use_time = ed_marker_move_use_time(mm);
+
+ /* Modal numinput active, try to handle numeric inputs first... */
+ if (event->val == KM_PRESS && has_numinput && handleNumInput(C, &mm->num, event)) {
+ float value = (float)RNA_int_get(op->ptr, "frames");
+
+ applyNumInput(&mm->num, &value);
+ if (use_time) {
+ value = TIME2FRA(value);
+ }
+
+ RNA_int_set(op->ptr, "frames", (int)value);
+ ed_marker_move_apply(C, op);
+ ed_marker_move_update_header(C, op);
+ }
+ else {
+ bool handled = false;
+ switch (event->type) {
+ case ESCKEY:
+ ed_marker_move_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ case RIGHTMOUSE:
+ /* press = user manually demands transform to be canceled */
+ if (event->val == KM_PRESS) {
+ ed_marker_move_cancel(C, op);
+ return OPERATOR_CANCELLED;
+ }
+ /* else continue; <--- see if release event should be caught for tweak-end */
+ ATTR_FALLTHROUGH;
+
+ case RETKEY:
+ case PADENTER:
+ case LEFTMOUSE:
+ case MIDDLEMOUSE:
+ if (WM_event_is_modal_tweak_exit(event, mm->event_type)) {
+ ed_marker_move_exit(C, op);
+ WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
+ return OPERATOR_FINISHED;
+ }
+ break;
+ case MOUSEMOVE:
+ if (!has_numinput) {
+ float dx;
+
+ dx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
+
+ if (event->x != mm->evtx) { /* XXX maybe init for first time */
+ float fac;
+
+ mm->evtx = event->x;
+ fac = ((float)(event->x - mm->firstx) * dx);
+
+ apply_keyb_grid(event->shift,
+ event->ctrl,
+ &fac,
+ 0.0,
+ 1.0,
+ 0.1,
+ 0 /*was: U.flag & USER_AUTOGRABGRID*/);
+
+ RNA_int_set(op->ptr, "frames", (int)fac);
+ ed_marker_move_apply(C, op);
+ ed_marker_move_update_header(C, op);
+ }
+ }
+ break;
+ }
+
+ if (!handled && event->val == KM_PRESS && handleNumInput(C, &mm->num, event)) {
+ float value = (float)RNA_int_get(op->ptr, "frames");
+
+ applyNumInput(&mm->num, &value);
+ if (use_time) {
+ value = TIME2FRA(value);
+ }
+
+ RNA_int_set(op->ptr, "frames", (int)value);
+ ed_marker_move_apply(C, op);
+ ed_marker_move_update_header(C, op);
+ }
+ }
+
+ return OPERATOR_RUNNING_MODAL;
}
static int ed_marker_move_exec(bContext *C, wmOperator *op)
{
- if (ed_marker_move_init(C, op)) {
- ed_marker_move_apply(C, op);
- ed_marker_move_exit(C, op);
- return OPERATOR_FINISHED;
- }
- return OPERATOR_PASS_THROUGH;
+ if (ed_marker_move_init(C, op)) {
+ ed_marker_move_apply(C, op);
+ ed_marker_move_exit(C, op);
+ return OPERATOR_FINISHED;
+ }
+ return OPERATOR_PASS_THROUGH;
}
static void MARKER_OT_move(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Move Time Marker";
- ot->description = "Move selected time marker(s)";
- ot->idname = "MARKER_OT_move";
-
- /* api callbacks */
- ot->exec = ed_marker_move_exec;
- ot->invoke = ed_marker_move_invoke_wrapper;
- ot->modal = ed_marker_move_modal;
- ot->poll = ed_markers_poll_selected_no_locked_markers;
- ot->cancel = ed_marker_move_cancel;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
-
- /* rna storage */
- RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
+ /* identifiers */
+ ot->name = "Move Time Marker";
+ ot->description = "Move selected time marker(s)";
+ ot->idname = "MARKER_OT_move";
+
+ /* api callbacks */
+ ot->exec = ed_marker_move_exec;
+ ot->invoke = ed_marker_move_invoke_wrapper;
+ ot->modal = ed_marker_move_modal;
+ ot->poll = ed_markers_poll_selected_no_locked_markers;
+ ot->cancel = ed_marker_move_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO | OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR;
+
+ /* rna storage */
+ RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
}
/* ************************** duplicate markers *************************** */
@@ -1065,76 +1076,75 @@ static void MARKER_OT_move(wmOperatorType *ot)
/* duplicate selected TimeMarkers */
static void ed_marker_duplicate_apply(bContext *C)
{
- ListBase *markers = ED_context_get_markers(C);
- TimeMarker *marker, *newmarker;
-
- if (markers == NULL)
- return;
-
- /* go through the list of markers, duplicate selected markers and add duplicated copies
- * to the beginning of the list (unselect original markers)
- */
- for (marker = markers->first; marker; marker = marker->next) {
- if (marker->flag & SELECT) {
- /* unselect selected marker */
- marker->flag &= ~SELECT;
-
- /* create and set up new marker */
- newmarker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
- newmarker->flag = SELECT;
- newmarker->frame = marker->frame;
- BLI_strncpy(newmarker->name, marker->name, sizeof(marker->name));
+ ListBase *markers = ED_context_get_markers(C);
+ TimeMarker *marker, *newmarker;
+
+ if (markers == NULL)
+ return;
+
+ /* go through the list of markers, duplicate selected markers and add duplicated copies
+ * to the beginning of the list (unselect original markers)
+ */
+ for (marker = markers->first; marker; marker = marker->next) {
+ if (marker->flag & SELECT) {
+ /* unselect selected marker */
+ marker->flag &= ~SELECT;
+
+ /* create and set up new marker */
+ newmarker = MEM_callocN(sizeof(TimeMarker), "TimeMarker");
+ newmarker->flag = SELECT;
+ newmarker->frame = marker->frame;
+ BLI_strncpy(newmarker->name, marker->name, sizeof(marker->name));
#ifdef DURIAN_CAMERA_SWITCH
- newmarker->camera = marker->camera;
+ newmarker->camera = marker->camera;
#endif
- /* new marker is added to the beginning of list */
- // FIXME: bad ordering!
- BLI_addhead(markers, newmarker);
- }
- }
+ /* new marker is added to the beginning of list */
+ // FIXME: bad ordering!
+ BLI_addhead(markers, newmarker);
+ }
+ }
}
static int ed_marker_duplicate_exec(bContext *C, wmOperator *op)
{
- ed_marker_duplicate_apply(C);
- ed_marker_move_exec(C, op); /* assumes frs delta set */
-
- return OPERATOR_FINISHED;
+ ed_marker_duplicate_apply(C);
+ ed_marker_move_exec(C, op); /* assumes frs delta set */
+ return OPERATOR_FINISHED;
}
static int ed_marker_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- ed_marker_duplicate_apply(C);
- return ed_marker_move_invoke(C, op, event);
+ ed_marker_duplicate_apply(C);
+ return ed_marker_move_invoke(C, op, event);
}
static int ed_marker_duplicate_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, event, ed_marker_duplicate_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, ed_marker_duplicate_invoke);
}
static void MARKER_OT_duplicate(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Duplicate Time Marker";
- ot->description = "Duplicate selected time marker(s)";
- ot->idname = "MARKER_OT_duplicate";
-
- /* api callbacks */
- ot->exec = ed_marker_duplicate_exec;
- ot->invoke = ed_marker_duplicate_invoke_wrapper;
- ot->modal = ed_marker_move_modal;
- ot->poll = ed_markers_poll_selected_no_locked_markers;
- ot->cancel = ed_marker_move_cancel;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* rna storage */
- RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
+ /* identifiers */
+ ot->name = "Duplicate Time Marker";
+ ot->description = "Duplicate selected time marker(s)";
+ ot->idname = "MARKER_OT_duplicate";
+
+ /* api callbacks */
+ ot->exec = ed_marker_duplicate_exec;
+ ot->invoke = ed_marker_duplicate_invoke_wrapper;
+ ot->modal = ed_marker_move_modal;
+ ot->poll = ed_markers_poll_selected_no_locked_markers;
+ ot->cancel = ed_marker_move_cancel;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* rna storage */
+ RNA_def_int(ot->srna, "frames", 0, INT_MIN, INT_MAX, "Frames", "", INT_MIN, INT_MAX);
}
/* ************************** selection ************************************/
@@ -1142,137 +1152,136 @@ static void MARKER_OT_duplicate(wmOperatorType *ot)
/* select/deselect TimeMarker at current frame */
static void select_timeline_marker_frame(ListBase *markers, int frame, bool extend)
{
- TimeMarker *marker, *marker_first = NULL;
-
- /* support for selection cycling */
- for (marker = markers->first; marker; marker = marker->next) {
- if (marker->frame == frame) {
- if (marker->flag & SELECT) {
- marker_first = marker->next;
- break;
- }
- }
- }
-
- /* if extend is not set, then deselect markers */
- if (extend == false) {
- for (marker = markers->first; marker; marker = marker->next) {
- marker->flag &= ~SELECT;
- }
- }
-
- LISTBASE_CIRCULAR_FORWARD_BEGIN(markers, marker, marker_first)
- {
- /* this way a not-extend select will always give 1 selected marker */
- if (marker->frame == frame) {
- marker->flag ^= SELECT;
- break;
- }
- }
- LISTBASE_CIRCULAR_FORWARD_END(markers, marker, marker_first);
+ TimeMarker *marker, *marker_first = NULL;
+
+ /* support for selection cycling */
+ for (marker = markers->first; marker; marker = marker->next) {
+ if (marker->frame == frame) {
+ if (marker->flag & SELECT) {
+ marker_first = marker->next;
+ break;
+ }
+ }
+ }
+
+ /* if extend is not set, then deselect markers */
+ if (extend == false) {
+ for (marker = markers->first; marker; marker = marker->next) {
+ marker->flag &= ~SELECT;
+ }
+ }
+
+ LISTBASE_CIRCULAR_FORWARD_BEGIN (markers, marker, marker_first) {
+ /* this way a not-extend select will always give 1 selected marker */
+ if (marker->frame == frame) {
+ marker->flag ^= SELECT;
+ break;
+ }
+ }
+ LISTBASE_CIRCULAR_FORWARD_END(markers, marker, marker_first);
}
static int ed_marker_select(bContext *C, const wmEvent *event, bool extend, bool camera)
{
- ListBase *markers = ED_context_get_markers(C);
- ARegion *ar = CTX_wm_region(C);
- View2D *v2d = UI_view2d_fromcontext(C);
- float viewx;
- int x, cfra;
+ ListBase *markers = ED_context_get_markers(C);
+ ARegion *ar = CTX_wm_region(C);
+ View2D *v2d = UI_view2d_fromcontext(C);
+ float viewx;
+ int x, cfra;
- if (markers == NULL)
- return OPERATOR_PASS_THROUGH;
+ if (markers == NULL)
+ return OPERATOR_PASS_THROUGH;
- x = event->x - ar->winrct.xmin;
+ x = event->x - ar->winrct.xmin;
- viewx = UI_view2d_region_to_view_x(v2d, x);
+ viewx = UI_view2d_region_to_view_x(v2d, x);
- cfra = ED_markers_find_nearest_marker_time(markers, viewx);
+ cfra = ED_markers_find_nearest_marker_time(markers, viewx);
- select_timeline_marker_frame(markers, cfra, extend);
+ select_timeline_marker_frame(markers, cfra, extend);
#ifdef DURIAN_CAMERA_SWITCH
- if (camera) {
- Scene *scene = CTX_data_scene(C);
- ViewLayer *view_layer = CTX_data_view_layer(C);
- Base *base;
- TimeMarker *marker;
- int sel = 0;
-
- if (!extend)
- BKE_view_layer_base_deselect_all(view_layer);
-
- for (marker = markers->first; marker; marker = marker->next) {
- if (marker->frame == cfra) {
- sel = (marker->flag & SELECT);
- break;
- }
- }
-
- for (marker = markers->first; marker; marker = marker->next) {
- if (marker->camera) {
- if (marker->frame == cfra) {
- base = BKE_view_layer_base_find(view_layer, marker->camera);
- if (base) {
- ED_object_base_select(base, sel);
- if (sel)
- ED_object_base_activate(C, base);
- }
- }
- }
- }
-
- DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
- WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
- }
+ if (camera) {
+ Scene *scene = CTX_data_scene(C);
+ ViewLayer *view_layer = CTX_data_view_layer(C);
+ Base *base;
+ TimeMarker *marker;
+ int sel = 0;
+
+ if (!extend)
+ BKE_view_layer_base_deselect_all(view_layer);
+
+ for (marker = markers->first; marker; marker = marker->next) {
+ if (marker->frame == cfra) {
+ sel = (marker->flag & SELECT);
+ break;
+ }
+ }
+
+ for (marker = markers->first; marker; marker = marker->next) {
+ if (marker->camera) {
+ if (marker->frame == cfra) {
+ base = BKE_view_layer_base_find(view_layer, marker->camera);
+ if (base) {
+ ED_object_base_select(base, sel);
+ if (sel)
+ ED_object_base_activate(C, base);
+ }
+ }
+ }
+ }
+
+ DEG_id_tag_update(&scene->id, ID_RECALC_SELECT);
+ WM_event_add_notifier(C, NC_SCENE | ND_OB_SELECT, scene);
+ }
#else
- (void)camera;
+ (void)camera;
#endif
- WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
- /* allowing tweaks, but needs OPERATOR_FINISHED, otherwise renaming fails... [#25987] */
- return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
+ /* allowing tweaks, but needs OPERATOR_FINISHED, otherwise renaming fails... [#25987] */
+ return OPERATOR_FINISHED | OPERATOR_PASS_THROUGH;
}
static int ed_marker_select_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- const bool extend = RNA_boolean_get(op->ptr, "extend");
- bool camera = false;
+ const bool extend = RNA_boolean_get(op->ptr, "extend");
+ bool camera = false;
#ifdef DURIAN_CAMERA_SWITCH
- camera = RNA_boolean_get(op->ptr, "camera");
+ camera = RNA_boolean_get(op->ptr, "camera");
#endif
- return ed_marker_select(C, event, extend, camera);
+ return ed_marker_select(C, event, extend, camera);
}
static int ed_marker_select_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, event, ed_marker_select_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, ed_marker_select_invoke);
}
static void MARKER_OT_select(wmOperatorType *ot)
{
- PropertyRNA *prop;
+ PropertyRNA *prop;
- /* identifiers */
- ot->name = "Select Time Marker";
- ot->description = "Select time marker(s)";
- ot->idname = "MARKER_OT_select";
+ /* identifiers */
+ ot->name = "Select Time Marker";
+ ot->description = "Select time marker(s)";
+ ot->idname = "MARKER_OT_select";
- /* api callbacks */
- ot->invoke = ed_marker_select_invoke_wrapper;
- ot->poll = ed_markers_poll_markers_exist;
+ /* api callbacks */
+ ot->invoke = ed_marker_select_invoke_wrapper;
+ ot->poll = ed_markers_poll_markers_exist;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "extend", 0, "Extend", "Extend the selection");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
#ifdef DURIAN_CAMERA_SWITCH
- prop = RNA_def_boolean(ot->srna, "camera", 0, "Camera", "Select the camera");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ prop = RNA_def_boolean(ot->srna, "camera", 0, "Camera", "Select the camera");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
#endif
}
@@ -1286,110 +1295,110 @@ static void MARKER_OT_select(wmOperatorType *ot)
*
* callbacks:
*
- * exec() has to be filled in by user
+ * exec() has to be filled in by user
*
* invoke() default WM function
* adds modal handler
*
- * modal() default WM function
+ * modal() default WM function
* accept modal events while doing it, calls exec(), handles ESC and border drawing
*
- * poll() has to be filled in by user for context
+ * poll() has to be filled in by user for context
*/
static int ed_marker_box_select_exec(bContext *C, wmOperator *op)
{
- View2D *v2d = UI_view2d_fromcontext(C);
- ListBase *markers = ED_context_get_markers(C);
- rctf rect;
+ View2D *v2d = UI_view2d_fromcontext(C);
+ ListBase *markers = ED_context_get_markers(C);
+ rctf rect;
- WM_operator_properties_border_to_rctf(op, &rect);
- UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
+ WM_operator_properties_border_to_rctf(op, &rect);
+ UI_view2d_region_to_view_rctf(v2d, &rect, &rect);
- if (markers == NULL)
- return 0;
+ if (markers == NULL)
+ return 0;
- 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)) {
- ED_markers_deselect_all(markers, SEL_DESELECT);
- }
+ 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)) {
+ ED_markers_deselect_all(markers, SEL_DESELECT);
+ }
- for (TimeMarker *marker = markers->first; marker; marker = marker->next) {
- if (BLI_rctf_isect_x(&rect, marker->frame)) {
- SET_FLAG_FROM_TEST(marker->flag, select, SELECT);
- }
- }
+ for (TimeMarker *marker = markers->first; marker; marker = marker->next) {
+ if (BLI_rctf_isect_x(&rect, marker->frame)) {
+ SET_FLAG_FROM_TEST(marker->flag, select, SELECT);
+ }
+ }
- WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
- return 1;
+ return 1;
}
static int ed_marker_select_box_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, event, WM_gesture_box_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, WM_gesture_box_invoke);
}
static void MARKER_OT_select_box(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Marker Box Select";
- ot->description = "Select all time markers using box selection";
- ot->idname = "MARKER_OT_select_box";
+ /* identifiers */
+ ot->name = "Marker Box Select";
+ ot->description = "Select all time markers using box selection";
+ ot->idname = "MARKER_OT_select_box";
- /* api callbacks */
- ot->exec = ed_marker_box_select_exec;
- ot->invoke = ed_marker_select_box_invoke_wrapper;
- ot->modal = WM_gesture_box_modal;
- ot->cancel = WM_gesture_box_cancel;
+ /* api callbacks */
+ ot->exec = ed_marker_box_select_exec;
+ ot->invoke = ed_marker_select_box_invoke_wrapper;
+ ot->modal = WM_gesture_box_modal;
+ ot->cancel = WM_gesture_box_cancel;
- ot->poll = ed_markers_poll_markers_exist;
+ ot->poll = ed_markers_poll_markers_exist;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- WM_operator_properties_gesture_box(ot);
- WM_operator_properties_select_operation_simple(ot);
+ /* properties */
+ WM_operator_properties_gesture_box(ot);
+ WM_operator_properties_select_operation_simple(ot);
}
/* *********************** (de)select all ***************** */
static int ed_marker_select_all_exec(bContext *C, wmOperator *op)
{
- ListBase *markers = ED_context_get_markers(C);
- if (markers == NULL) {
- return OPERATOR_CANCELLED;
- }
+ ListBase *markers = ED_context_get_markers(C);
+ if (markers == NULL) {
+ return OPERATOR_CANCELLED;
+ }
- int action = RNA_enum_get(op->ptr, "action");
- ED_markers_deselect_all(markers, action);
+ int action = RNA_enum_get(op->ptr, "action");
+ ED_markers_deselect_all(markers, action);
- WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void MARKER_OT_select_all(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "(De)select all Markers";
- ot->description = "Change selection of all time markers";
- ot->idname = "MARKER_OT_select_all";
+ /* identifiers */
+ ot->name = "(De)select all Markers";
+ ot->description = "Change selection of all time markers";
+ ot->idname = "MARKER_OT_select_all";
- /* api callbacks */
- ot->exec = ed_marker_select_all_exec;
- ot->invoke = ed_markers_opwrap_invoke;
- ot->poll = ed_markers_poll_markers_exist;
+ /* api callbacks */
+ ot->exec = ed_marker_select_all_exec;
+ ot->invoke = ed_markers_opwrap_invoke;
+ ot->poll = ed_markers_poll_markers_exist;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* rna */
- WM_operator_properties_select_all(ot);
+ /* rna */
+ WM_operator_properties_select_all(ot);
}
/* ***************** remove marker *********************** */
@@ -1397,167 +1406,172 @@ static void MARKER_OT_select_all(wmOperatorType *ot)
/* remove selected TimeMarkers */
static int ed_marker_delete_exec(bContext *C, wmOperator *UNUSED(op))
{
- ListBase *markers = ED_context_get_markers(C);
- TimeMarker *marker, *nmarker;
- bool changed = false;
-
- if (markers == NULL)
- return OPERATOR_CANCELLED;
-
- for (marker = markers->first; marker; marker = nmarker) {
- nmarker = marker->next;
- if (marker->flag & SELECT) {
- BLI_freelinkN(markers, marker);
- changed = true;
- }
- }
-
- if (changed) {
- WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
- }
-
- return OPERATOR_FINISHED;
+ ListBase *markers = ED_context_get_markers(C);
+ TimeMarker *marker, *nmarker;
+ bool changed = false;
+
+ if (markers == NULL)
+ return OPERATOR_CANCELLED;
+
+ for (marker = markers->first; marker; marker = nmarker) {
+ nmarker = marker->next;
+ if (marker->flag & SELECT) {
+ BLI_freelinkN(markers, marker);
+ changed = true;
+ }
+ }
+
+ if (changed) {
+ WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
+ }
+
+ return OPERATOR_FINISHED;
}
static int ed_marker_delete_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- // XXX: must we keep these confirmations?
- return ed_markers_opwrap_invoke_custom(C, op, event, WM_operator_confirm);
+ // XXX: must we keep these confirmations?
+ return ed_markers_opwrap_invoke_custom(C, op, event, WM_operator_confirm);
}
static void MARKER_OT_delete(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Delete Markers";
- ot->description = "Delete selected time marker(s)";
- ot->idname = "MARKER_OT_delete";
-
- /* api callbacks */
- ot->invoke = ed_marker_delete_invoke_wrapper;
- ot->exec = ed_marker_delete_exec;
- ot->poll = ed_markers_poll_selected_no_locked_markers;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* identifiers */
+ ot->name = "Delete Markers";
+ ot->description = "Delete selected time marker(s)";
+ ot->idname = "MARKER_OT_delete";
+
+ /* api callbacks */
+ ot->invoke = ed_marker_delete_invoke_wrapper;
+ ot->exec = ed_marker_delete_exec;
+ ot->poll = ed_markers_poll_selected_no_locked_markers;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
/* **************** rename marker ***************** */
/* rename first selected TimeMarker */
static int ed_marker_rename_exec(bContext *C, wmOperator *op)
{
- TimeMarker *marker = ED_markers_get_first_selected(ED_context_get_markers(C));
+ TimeMarker *marker = ED_markers_get_first_selected(ED_context_get_markers(C));
- if (marker) {
- RNA_string_get(op->ptr, "name", marker->name);
+ if (marker) {
+ RNA_string_get(op->ptr, "name", marker->name);
- WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
static int ed_marker_rename_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
{
- /* must initialize the marker name first if there is a marker selected */
- TimeMarker *marker = ED_markers_get_first_selected(ED_context_get_markers(C));
- if (marker)
- RNA_string_set(op->ptr, "name", marker->name);
+ /* must initialize the marker name first if there is a marker selected */
+ TimeMarker *marker = ED_markers_get_first_selected(ED_context_get_markers(C));
+ if (marker)
+ RNA_string_set(op->ptr, "name", marker->name);
- /* now see if the operator is usable */
- return ed_markers_opwrap_invoke_custom(C, op, event, WM_operator_props_popup_confirm);
+ /* now see if the operator is usable */
+ return ed_markers_opwrap_invoke_custom(C, op, event, WM_operator_props_popup_confirm);
}
static void MARKER_OT_rename(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Rename Marker";
- ot->description = "Rename first selected time marker";
- ot->idname = "MARKER_OT_rename";
-
- /* api callbacks */
- ot->invoke = ed_marker_rename_invoke_wrapper;
- ot->exec = ed_marker_rename_exec;
- ot->poll = ed_markers_poll_selected_no_locked_markers;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- ot->prop = RNA_def_string(ot->srna, "name", "RenamedMarker", sizeof(((TimeMarker *)NULL)->name), "Name", "New name for marker");
- //RNA_def_boolean(ot->srna, "ensure_unique", 0, "Ensure Unique", "Ensure that new name is unique within collection of markers");
+ /* identifiers */
+ ot->name = "Rename Marker";
+ ot->description = "Rename first selected time marker";
+ ot->idname = "MARKER_OT_rename";
+
+ /* api callbacks */
+ ot->invoke = ed_marker_rename_invoke_wrapper;
+ ot->exec = ed_marker_rename_exec;
+ ot->poll = ed_markers_poll_selected_no_locked_markers;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ ot->prop = RNA_def_string(ot->srna,
+ "name",
+ "RenamedMarker",
+ sizeof(((TimeMarker *)NULL)->name),
+ "Name",
+ "New name for marker");
+ //RNA_def_boolean(ot->srna, "ensure_unique", 0, "Ensure Unique", "Ensure that new name is unique within collection of markers");
}
/* **************** make links to scene ***************** */
static int ed_marker_make_links_scene_exec(bContext *C, wmOperator *op)
{
- ListBase *markers = ED_context_get_markers(C);
- Scene *scene_to = BLI_findlink(&CTX_data_main(C)->scenes, RNA_enum_get(op->ptr, "scene"));
- TimeMarker *marker, *marker_new;
-
- if (scene_to == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Scene not found");
- return OPERATOR_CANCELLED;
- }
-
- if (scene_to == CTX_data_scene(C)) {
- BKE_report(op->reports, RPT_ERROR, "Cannot re-link markers into the same scene");
- return OPERATOR_CANCELLED;
- }
-
- if (scene_to->toolsettings->lock_markers) {
- BKE_report(op->reports, RPT_ERROR, "Target scene has locked markers");
- return OPERATOR_CANCELLED;
- }
-
- /* copy markers */
- for (marker = markers->first; marker; marker = marker->next) {
- if (marker->flag & SELECT) {
- marker_new = MEM_dupallocN(marker);
- marker_new->prev = marker_new->next = NULL;
-
- BLI_addtail(&scene_to->markers, marker_new);
- }
- }
-
- return OPERATOR_FINISHED;
+ ListBase *markers = ED_context_get_markers(C);
+ Scene *scene_to = BLI_findlink(&CTX_data_main(C)->scenes, RNA_enum_get(op->ptr, "scene"));
+ TimeMarker *marker, *marker_new;
+
+ if (scene_to == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Scene not found");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (scene_to == CTX_data_scene(C)) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot re-link markers into the same scene");
+ return OPERATOR_CANCELLED;
+ }
+
+ if (scene_to->toolsettings->lock_markers) {
+ BKE_report(op->reports, RPT_ERROR, "Target scene has locked markers");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* copy markers */
+ for (marker = markers->first; marker; marker = marker->next) {
+ if (marker->flag & SELECT) {
+ marker_new = MEM_dupallocN(marker);
+ marker_new->prev = marker_new->next = NULL;
+
+ BLI_addtail(&scene_to->markers, marker_new);
+ }
+ }
+
+ return OPERATOR_FINISHED;
}
-static int ed_marker_make_links_scene_invoke_wrapper(bContext *C, wmOperator *op, const wmEvent *event)
+static int ed_marker_make_links_scene_invoke_wrapper(bContext *C,
+ wmOperator *op,
+ const wmEvent *event)
{
- return ed_markers_opwrap_invoke_custom(C, op, event, WM_menu_invoke);
+ return ed_markers_opwrap_invoke_custom(C, op, event, WM_menu_invoke);
}
static void MARKER_OT_make_links_scene(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Make Links to Scene";
- ot->description = "Copy selected markers to another scene";
- ot->idname = "MARKER_OT_make_links_scene";
-
- /* api callbacks */
- ot->exec = ed_marker_make_links_scene_exec;
- ot->invoke = ed_marker_make_links_scene_invoke_wrapper;
- ot->poll = ed_markers_poll_selected_markers;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* properties */
- prop = RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", "");
- RNA_def_enum_funcs(prop, RNA_scene_itemf);
- RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
- ot->prop = prop;
-
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Make Links to Scene";
+ ot->description = "Copy selected markers to another scene";
+ ot->idname = "MARKER_OT_make_links_scene";
+
+ /* api callbacks */
+ ot->exec = ed_marker_make_links_scene_exec;
+ ot->invoke = ed_marker_make_links_scene_invoke_wrapper;
+ ot->poll = ed_markers_poll_selected_markers;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* properties */
+ prop = RNA_def_enum(ot->srna, "scene", DummyRNA_NULL_items, 0, "Scene", "");
+ RNA_def_enum_funcs(prop, RNA_scene_itemf);
+ RNA_def_property_flag(prop, PROP_ENUM_NO_TRANSLATE);
+ ot->prop = prop;
}
#ifdef DURIAN_CAMERA_SWITCH
@@ -1565,65 +1579,65 @@ static void MARKER_OT_make_links_scene(wmOperatorType *ot)
static int ed_marker_camera_bind_exec(bContext *C, wmOperator *op)
{
- bScreen *sc = CTX_wm_screen(C);
- Scene *scene = CTX_data_scene(C);
- Object *ob = CTX_data_active_object(C);
- ListBase *markers = ED_context_get_markers(C);
- TimeMarker *marker;
-
- /* Don't do anything if we don't have a camera selected */
- if (ob == NULL) {
- BKE_report(op->reports, RPT_ERROR, "Select a camera to bind to a marker on this frame");
- return OPERATOR_CANCELLED;
- }
-
- /* add new marker, unless we already have one on this frame, in which case, replace it */
- if (markers == NULL)
- return OPERATOR_CANCELLED;
-
- marker = ED_markers_find_nearest_marker(markers, CFRA);
- if ((marker == NULL) || (marker->frame != CFRA)) {
- marker = MEM_callocN(sizeof(TimeMarker), "Camera TimeMarker");
- marker->flag = SELECT;
- marker->frame = CFRA;
- BLI_addtail(markers, marker);
-
- /* deselect all others, so that the user can then move it without problems */
- for (TimeMarker *m = markers->first; m; m = m->next) {
- if (m != marker) {
- m->flag &= ~SELECT;
- }
- }
- }
-
- /* bind to the nominated camera (as set in operator props) */
- marker->camera = ob;
-
- /* camera may have changes */
- BKE_scene_camera_switch_update(scene);
- BKE_screen_view3d_scene_sync(sc, scene);
-
- WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
- WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
- WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene); /* so we get view3d redraws */
-
- return OPERATOR_FINISHED;
+ bScreen *sc = CTX_wm_screen(C);
+ Scene *scene = CTX_data_scene(C);
+ Object *ob = CTX_data_active_object(C);
+ ListBase *markers = ED_context_get_markers(C);
+ TimeMarker *marker;
+
+ /* Don't do anything if we don't have a camera selected */
+ if (ob == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "Select a camera to bind to a marker on this frame");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* add new marker, unless we already have one on this frame, in which case, replace it */
+ if (markers == NULL)
+ return OPERATOR_CANCELLED;
+
+ marker = ED_markers_find_nearest_marker(markers, CFRA);
+ if ((marker == NULL) || (marker->frame != CFRA)) {
+ marker = MEM_callocN(sizeof(TimeMarker), "Camera TimeMarker");
+ marker->flag = SELECT;
+ marker->frame = CFRA;
+ BLI_addtail(markers, marker);
+
+ /* deselect all others, so that the user can then move it without problems */
+ for (TimeMarker *m = markers->first; m; m = m->next) {
+ if (m != marker) {
+ m->flag &= ~SELECT;
+ }
+ }
+ }
+
+ /* bind to the nominated camera (as set in operator props) */
+ marker->camera = ob;
+
+ /* camera may have changes */
+ BKE_scene_camera_switch_update(scene);
+ BKE_screen_view3d_scene_sync(sc, scene);
+
+ WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
+ WM_event_add_notifier(C, NC_SCENE | NA_EDITED, scene); /* so we get view3d redraws */
+
+ return OPERATOR_FINISHED;
}
static void MARKER_OT_camera_bind(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Bind Camera to Markers";
- ot->description = "Bind the selected camera to a marker on the current frame";
- ot->idname = "MARKER_OT_camera_bind";
-
- /* api callbacks */
- ot->exec = ed_marker_camera_bind_exec;
- ot->invoke = ed_markers_opwrap_invoke;
- ot->poll = ED_operator_animview_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* identifiers */
+ ot->name = "Bind Camera to Markers";
+ ot->description = "Bind the selected camera to a marker on the current frame";
+ ot->idname = "MARKER_OT_camera_bind";
+
+ /* api callbacks */
+ ot->exec = ed_marker_camera_bind_exec;
+ ot->invoke = ed_markers_opwrap_invoke;
+ ot->poll = ED_operator_animview_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
#endif
@@ -1632,22 +1646,22 @@ static void MARKER_OT_camera_bind(wmOperatorType *ot)
/* called in screen_ops.c:ED_operatortypes_screen() */
void ED_operatortypes_marker(void)
{
- WM_operatortype_append(MARKER_OT_add);
- WM_operatortype_append(MARKER_OT_move);
- WM_operatortype_append(MARKER_OT_duplicate);
- WM_operatortype_append(MARKER_OT_select);
- WM_operatortype_append(MARKER_OT_select_box);
- WM_operatortype_append(MARKER_OT_select_all);
- WM_operatortype_append(MARKER_OT_delete);
- WM_operatortype_append(MARKER_OT_rename);
- WM_operatortype_append(MARKER_OT_make_links_scene);
+ WM_operatortype_append(MARKER_OT_add);
+ WM_operatortype_append(MARKER_OT_move);
+ WM_operatortype_append(MARKER_OT_duplicate);
+ WM_operatortype_append(MARKER_OT_select);
+ WM_operatortype_append(MARKER_OT_select_box);
+ WM_operatortype_append(MARKER_OT_select_all);
+ WM_operatortype_append(MARKER_OT_delete);
+ WM_operatortype_append(MARKER_OT_rename);
+ WM_operatortype_append(MARKER_OT_make_links_scene);
#ifdef DURIAN_CAMERA_SWITCH
- WM_operatortype_append(MARKER_OT_camera_bind);
+ WM_operatortype_append(MARKER_OT_camera_bind);
#endif
}
/* called in screen_ops.c:ED_keymap_screen() */
void ED_keymap_marker(wmKeyConfig *keyconf)
{
- WM_keymap_ensure(keyconf, "Markers", 0, 0);
+ WM_keymap_ensure(keyconf, "Markers", 0, 0);
}
diff --git a/source/blender/editors/animation/anim_motion_paths.c b/source/blender/editors/animation/anim_motion_paths.c
index 7023a138c96..b1183167945 100644
--- a/source/blender/editors/animation/anim_motion_paths.c
+++ b/source/blender/editors/animation/anim_motion_paths.c
@@ -48,23 +48,22 @@
static CLG_LogRef LOG = {"ed.anim.motion_paths"};
-
/* Motion path needing to be baked (mpt) */
typedef struct MPathTarget {
- struct MPathTarget *next, *prev;
+ struct MPathTarget *next, *prev;
- bMotionPath *mpath; /* motion path in question */
+ bMotionPath *mpath; /* motion path in question */
- DLRBT_Tree keys; /* temp, to know where the keyframes are */
+ DLRBT_Tree keys; /* temp, to know where the keyframes are */
- /* Original (Source Objects) */
- Object *ob; /* source object */
- bPoseChannel *pchan; /* source posechannel (if applicable) */
+ /* Original (Source Objects) */
+ Object *ob; /* source object */
+ bPoseChannel *pchan; /* source posechannel (if applicable) */
- /* "Evaluated" Copies (these come from the background COW copie
- * that provide all the coordinates we want to save off)
- */
- Object *ob_eval; /* evaluated object */
+ /* "Evaluated" Copies (these come from the background COW copie
+ * that provide all the coordinates we want to save off)
+ */
+ Object *ob_eval; /* evaluated object */
} MPathTarget;
/* ........ */
@@ -75,54 +74,53 @@ typedef struct MPathTarget {
/* TODO: it would be nice in future to be able to update objects dependent on these bones too? */
void animviz_get_object_motionpaths(Object *ob, ListBase *targets)
{
- MPathTarget *mpt;
-
- /* object itself first */
- if ((ob->avs.recalc & ANIMVIZ_RECALC_PATHS) && (ob->mpath)) {
- /* new target for object */
- mpt = MEM_callocN(sizeof(MPathTarget), "MPathTarget Ob");
- BLI_addtail(targets, mpt);
-
- mpt->mpath = ob->mpath;
- mpt->ob = ob;
- }
-
- /* bones */
- if ((ob->pose) && (ob->pose->avs.recalc & ANIMVIZ_RECALC_PATHS)) {
- bArmature *arm = ob->data;
- bPoseChannel *pchan;
-
- for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
- if ((pchan->bone) && (arm->layer & pchan->bone->layer) && (pchan->mpath)) {
- /* new target for bone */
- mpt = MEM_callocN(sizeof(MPathTarget), "MPathTarget PoseBone");
- BLI_addtail(targets, mpt);
-
- mpt->mpath = pchan->mpath;
- mpt->ob = ob;
- mpt->pchan = pchan;
- }
- }
- }
+ MPathTarget *mpt;
+
+ /* object itself first */
+ if ((ob->avs.recalc & ANIMVIZ_RECALC_PATHS) && (ob->mpath)) {
+ /* new target for object */
+ mpt = MEM_callocN(sizeof(MPathTarget), "MPathTarget Ob");
+ BLI_addtail(targets, mpt);
+
+ mpt->mpath = ob->mpath;
+ mpt->ob = ob;
+ }
+
+ /* bones */
+ if ((ob->pose) && (ob->pose->avs.recalc & ANIMVIZ_RECALC_PATHS)) {
+ bArmature *arm = ob->data;
+ bPoseChannel *pchan;
+
+ for (pchan = ob->pose->chanbase.first; pchan; pchan = pchan->next) {
+ if ((pchan->bone) && (arm->layer & pchan->bone->layer) && (pchan->mpath)) {
+ /* new target for bone */
+ mpt = MEM_callocN(sizeof(MPathTarget), "MPathTarget PoseBone");
+ BLI_addtail(targets, mpt);
+
+ mpt->mpath = pchan->mpath;
+ mpt->ob = ob;
+ mpt->pchan = pchan;
+ }
+ }
+ }
}
/* ........ */
/* update scene for current frame */
-static void motionpaths_calc_update_scene(Main *bmain,
- struct Depsgraph *depsgraph)
+static void motionpaths_calc_update_scene(Main *bmain, struct Depsgraph *depsgraph)
{
- /* Do all updates
- * - if this is too slow, resort to using a more efficient way
- * that doesn't force complete update, but for now, this is the
- * most accurate way!
- *
- * TODO(segey): Bring back partial updates, which became impossible
- * with the new depsgraph due to unsorted nature of bases.
- *
- * TODO(sergey): Use evaluation context dedicated to motion paths.
- */
- BKE_scene_graph_update_for_newframe(depsgraph, bmain);
+ /* Do all updates
+ * - if this is too slow, resort to using a more efficient way
+ * that doesn't force complete update, but for now, this is the
+ * most accurate way!
+ *
+ * TODO(segey): Bring back partial updates, which became impossible
+ * with the new depsgraph due to unsorted nature of bases.
+ *
+ * TODO(sergey): Use evaluation context dedicated to motion paths.
+ */
+ BKE_scene_graph_update_for_newframe(depsgraph, bmain);
}
/* ........ */
@@ -130,78 +128,78 @@ static void motionpaths_calc_update_scene(Main *bmain,
/* perform baking for the targets on the current frame */
static void motionpaths_calc_bake_targets(ListBase *targets, int cframe)
{
- MPathTarget *mpt;
-
- /* for each target, check if it can be baked on the current frame */
- for (mpt = targets->first; mpt; mpt = mpt->next) {
- bMotionPath *mpath = mpt->mpath;
-
- /* current frame must be within the range the cache works for
- * - is inclusive of the first frame, but not the last otherwise we get buffer overruns
- */
- if ((cframe < mpath->start_frame) || (cframe >= mpath->end_frame)) {
- continue;
- }
-
- /* get the relevant cache vert to write to */
- bMotionPathVert *mpv = mpath->points + (cframe - mpath->start_frame);
-
- Object *ob_eval = mpt->ob_eval;
-
- /* Lookup evaluated pose channel, here because the depsgraph
- * evaluation can change them so they are not cached in mpt. */
- bPoseChannel *pchan_eval = NULL;
- if (mpt->pchan) {
- pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, mpt->pchan->name);
- }
-
- /* pose-channel or object path baking? */
- if (pchan_eval) {
- /* heads or tails */
- if (mpath->flag & MOTIONPATH_FLAG_BHEAD) {
- copy_v3_v3(mpv->co, pchan_eval->pose_head);
- }
- else {
- copy_v3_v3(mpv->co, pchan_eval->pose_tail);
- }
-
- /* result must be in worldspace */
- mul_m4_v3(ob_eval->obmat, mpv->co);
- }
- else {
- /* worldspace object location */
- copy_v3_v3(mpv->co, ob_eval->obmat[3]);
- }
-
- float mframe = (float)(cframe);
-
- /* Tag if it's a keyframe */
- if (BLI_dlrbTree_search_exact(&mpt->keys, compare_ak_cfraPtr, &mframe)) {
- mpv->flag |= MOTIONPATH_VERT_KEY;
- }
- else {
- mpv->flag &= ~MOTIONPATH_VERT_KEY;
- }
-
- /* Incremental update on evaluated object if possible, for fast updating
- * while dragging in transform. */
- bMotionPath *mpath_eval = NULL;
- if (mpt->pchan) {
- mpath_eval = (pchan_eval) ? pchan_eval->mpath : NULL;
- }
- else {
- mpath_eval = ob_eval->mpath;
- }
-
- if (mpath_eval && mpath_eval->length == mpath->length) {
- bMotionPathVert *mpv_eval = mpath_eval->points + (cframe - mpath_eval->start_frame);
- *mpv_eval = *mpv;
-
- GPU_VERTBUF_DISCARD_SAFE(mpath_eval->points_vbo);
- GPU_BATCH_DISCARD_SAFE(mpath_eval->batch_line);
- GPU_BATCH_DISCARD_SAFE(mpath_eval->batch_points);
- }
- }
+ MPathTarget *mpt;
+
+ /* for each target, check if it can be baked on the current frame */
+ for (mpt = targets->first; mpt; mpt = mpt->next) {
+ bMotionPath *mpath = mpt->mpath;
+
+ /* current frame must be within the range the cache works for
+ * - is inclusive of the first frame, but not the last otherwise we get buffer overruns
+ */
+ if ((cframe < mpath->start_frame) || (cframe >= mpath->end_frame)) {
+ continue;
+ }
+
+ /* get the relevant cache vert to write to */
+ bMotionPathVert *mpv = mpath->points + (cframe - mpath->start_frame);
+
+ Object *ob_eval = mpt->ob_eval;
+
+ /* Lookup evaluated pose channel, here because the depsgraph
+ * evaluation can change them so they are not cached in mpt. */
+ bPoseChannel *pchan_eval = NULL;
+ if (mpt->pchan) {
+ pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, mpt->pchan->name);
+ }
+
+ /* pose-channel or object path baking? */
+ if (pchan_eval) {
+ /* heads or tails */
+ if (mpath->flag & MOTIONPATH_FLAG_BHEAD) {
+ copy_v3_v3(mpv->co, pchan_eval->pose_head);
+ }
+ else {
+ copy_v3_v3(mpv->co, pchan_eval->pose_tail);
+ }
+
+ /* result must be in worldspace */
+ mul_m4_v3(ob_eval->obmat, mpv->co);
+ }
+ else {
+ /* worldspace object location */
+ copy_v3_v3(mpv->co, ob_eval->obmat[3]);
+ }
+
+ float mframe = (float)(cframe);
+
+ /* Tag if it's a keyframe */
+ if (BLI_dlrbTree_search_exact(&mpt->keys, compare_ak_cfraPtr, &mframe)) {
+ mpv->flag |= MOTIONPATH_VERT_KEY;
+ }
+ else {
+ mpv->flag &= ~MOTIONPATH_VERT_KEY;
+ }
+
+ /* Incremental update on evaluated object if possible, for fast updating
+ * while dragging in transform. */
+ bMotionPath *mpath_eval = NULL;
+ if (mpt->pchan) {
+ mpath_eval = (pchan_eval) ? pchan_eval->mpath : NULL;
+ }
+ else {
+ mpath_eval = ob_eval->mpath;
+ }
+
+ if (mpath_eval && mpath_eval->length == mpath->length) {
+ bMotionPathVert *mpv_eval = mpath_eval->points + (cframe - mpath_eval->start_frame);
+ *mpv_eval = *mpv;
+
+ GPU_VERTBUF_DISCARD_SAFE(mpath_eval->points_vbo);
+ GPU_BATCH_DISCARD_SAFE(mpath_eval->batch_line);
+ GPU_BATCH_DISCARD_SAFE(mpath_eval->batch_points);
+ }
+ }
}
/* Perform baking of the given object's and/or its bones' transforms to motion paths
@@ -217,119 +215,124 @@ void animviz_calc_motionpaths(Depsgraph *depsgraph,
bool restore,
bool current_frame_only)
{
- /* sanity check */
- if (ELEM(NULL, targets, targets->first))
- return;
-
- /* Compute frame range to bake within.
- * TODO: this method could be improved...
- * 1) max range for standard baking
- * 2) minimum range for recalc baking (i.e. between keyframes, but how?) */
- int sfra = INT_MAX;
- int efra = INT_MIN;
-
- for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
- /* try to increase area to do (only as much as needed) */
- sfra = MIN2(sfra, mpt->mpath->start_frame);
- efra = MAX2(efra, mpt->mpath->end_frame);
- }
-
- if (efra <= sfra) {
- return;
- }
-
- /* Limit frame range if we are updating just the current frame. */
- /* set frame values */
- int cfra = CFRA;
- if (current_frame_only) {
- if (cfra < sfra || cfra > efra) {
- return;
- }
- sfra = efra = cfra;
- }
-
- /* get copies of objects/bones to get the calculated results from
- * (for copy-on-write evaluation), so that we actually get some results
- */
- // TODO: Create a copy of background depsgraph that only contain these entities, and only evaluates them..
- for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
- mpt->ob_eval = DEG_get_evaluated_object(depsgraph, mpt->ob);
-
- AnimData *adt = BKE_animdata_from_id(&mpt->ob_eval->id);
-
- /* build list of all keyframes in active action for object or pchan */
- BLI_dlrbTree_init(&mpt->keys);
-
- if (adt) {
- bAnimVizSettings *avs;
-
- /* get pointer to animviz settings for each target */
- if (mpt->pchan)
- avs = &mpt->ob->pose->avs;
- else
- avs = &mpt->ob->avs;
-
- /* it is assumed that keyframes for bones are all grouped in a single group
- * unless an option is set to always use the whole action
- */
- if ((mpt->pchan) && (avs->path_viewflag & MOTIONPATH_VIEW_KFACT) == 0) {
- bActionGroup *agrp = BKE_action_group_find_name(adt->action, mpt->pchan->name);
-
- if (agrp) {
- agroup_to_keylist(adt, agrp, &mpt->keys, 0);
- }
- }
- else {
- action_to_keylist(adt, adt->action, &mpt->keys, 0);
- }
- }
- }
-
- /* calculate path over requested range */
- CLOG_INFO(&LOG, 1, "Calculating MotionPaths between frames %d - %d (%d frames)", sfra, efra, efra - sfra + 1);
- for (CFRA = sfra; CFRA <= efra; CFRA++) {
- if (current_frame_only) {
- /* For current frame, only update tagged. */
- BKE_scene_graph_update_tagged(depsgraph, bmain);
- }
- else {
- /* Update relevant data for new frame. */
- motionpaths_calc_update_scene(bmain, depsgraph);
- }
-
- /* perform baking for targets */
- motionpaths_calc_bake_targets(targets, CFRA);
- }
-
- /* reset original environment */
- /* NOTE: We don't always need to reevaluate the main scene, as the depsgraph
- * may be a temporary one that works on a subset of the data. We always have
- * to resoture the current frame though. */
- CFRA = cfra;
- if (!current_frame_only && restore) {
- motionpaths_calc_update_scene(bmain, depsgraph);
- }
-
- /* clear recalc flags from targets */
- for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
- bAnimVizSettings *avs;
- bMotionPath *mpath = mpt->mpath;
-
- /* get pointer to animviz settings for each target */
- if (mpt->pchan)
- avs = &mpt->ob->pose->avs;
- else
- avs = &mpt->ob->avs;
-
- /* clear the flag requesting recalculation of targets */
- avs->recalc &= ~ANIMVIZ_RECALC_PATHS;
-
- /* Clean temp data */
- BLI_dlrbTree_free(&mpt->keys);
-
- /* Free previous batches to force update. */
- GPU_VERTBUF_DISCARD_SAFE(mpath->points_vbo);
- GPU_BATCH_DISCARD_SAFE(mpath->batch_line);
- GPU_BATCH_DISCARD_SAFE(mpath->batch_points);
- }
+ /* sanity check */
+ if (ELEM(NULL, targets, targets->first))
+ return;
+
+ /* Compute frame range to bake within.
+ * TODO: this method could be improved...
+ * 1) max range for standard baking
+ * 2) minimum range for recalc baking (i.e. between keyframes, but how?) */
+ int sfra = INT_MAX;
+ int efra = INT_MIN;
+
+ for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
+ /* try to increase area to do (only as much as needed) */
+ sfra = MIN2(sfra, mpt->mpath->start_frame);
+ efra = MAX2(efra, mpt->mpath->end_frame);
+ }
+
+ if (efra <= sfra) {
+ return;
+ }
+
+ /* Limit frame range if we are updating just the current frame. */
+ /* set frame values */
+ int cfra = CFRA;
+ if (current_frame_only) {
+ if (cfra < sfra || cfra > efra) {
+ return;
+ }
+ sfra = efra = cfra;
+ }
+
+ /* get copies of objects/bones to get the calculated results from
+ * (for copy-on-write evaluation), so that we actually get some results
+ */
+ // TODO: Create a copy of background depsgraph that only contain these entities, and only evaluates them..
+ for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
+ mpt->ob_eval = DEG_get_evaluated_object(depsgraph, mpt->ob);
+
+ AnimData *adt = BKE_animdata_from_id(&mpt->ob_eval->id);
+
+ /* build list of all keyframes in active action for object or pchan */
+ BLI_dlrbTree_init(&mpt->keys);
+
+ if (adt) {
+ bAnimVizSettings *avs;
+
+ /* get pointer to animviz settings for each target */
+ if (mpt->pchan)
+ avs = &mpt->ob->pose->avs;
+ else
+ avs = &mpt->ob->avs;
+
+ /* it is assumed that keyframes for bones are all grouped in a single group
+ * unless an option is set to always use the whole action
+ */
+ if ((mpt->pchan) && (avs->path_viewflag & MOTIONPATH_VIEW_KFACT) == 0) {
+ bActionGroup *agrp = BKE_action_group_find_name(adt->action, mpt->pchan->name);
+
+ if (agrp) {
+ agroup_to_keylist(adt, agrp, &mpt->keys, 0);
+ }
+ }
+ else {
+ action_to_keylist(adt, adt->action, &mpt->keys, 0);
+ }
+ }
+ }
+
+ /* calculate path over requested range */
+ CLOG_INFO(&LOG,
+ 1,
+ "Calculating MotionPaths between frames %d - %d (%d frames)",
+ sfra,
+ efra,
+ efra - sfra + 1);
+ for (CFRA = sfra; CFRA <= efra; CFRA++) {
+ if (current_frame_only) {
+ /* For current frame, only update tagged. */
+ BKE_scene_graph_update_tagged(depsgraph, bmain);
+ }
+ else {
+ /* Update relevant data for new frame. */
+ motionpaths_calc_update_scene(bmain, depsgraph);
+ }
+
+ /* perform baking for targets */
+ motionpaths_calc_bake_targets(targets, CFRA);
+ }
+
+ /* reset original environment */
+ /* NOTE: We don't always need to reevaluate the main scene, as the depsgraph
+ * may be a temporary one that works on a subset of the data. We always have
+ * to resoture the current frame though. */
+ CFRA = cfra;
+ if (!current_frame_only && restore) {
+ motionpaths_calc_update_scene(bmain, depsgraph);
+ }
+
+ /* clear recalc flags from targets */
+ for (MPathTarget *mpt = targets->first; mpt; mpt = mpt->next) {
+ bAnimVizSettings *avs;
+ bMotionPath *mpath = mpt->mpath;
+
+ /* get pointer to animviz settings for each target */
+ if (mpt->pchan)
+ avs = &mpt->ob->pose->avs;
+ else
+ avs = &mpt->ob->avs;
+
+ /* clear the flag requesting recalculation of targets */
+ avs->recalc &= ~ANIMVIZ_RECALC_PATHS;
+
+ /* Clean temp data */
+ BLI_dlrbTree_free(&mpt->keys);
+
+ /* Free previous batches to force update. */
+ GPU_VERTBUF_DISCARD_SAFE(mpath->points_vbo);
+ GPU_BATCH_DISCARD_SAFE(mpath->batch_line);
+ GPU_BATCH_DISCARD_SAFE(mpath->batch_points);
+ }
}
diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c
index 2287f2e0347..91cbc2ff3e0 100644
--- a/source/blender/editors/animation/anim_ops.c
+++ b/source/blender/editors/animation/anim_ops.c
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
#include <stdlib.h>
#include <math.h>
@@ -60,61 +59,62 @@
/* Check if the operator can be run from the current context */
static bool change_frame_poll(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
-
- /* XXX temp? prevent changes during render */
- if (G.is_rendering) return false;
-
- /* although it's only included in keymaps for regions using ED_KEYMAP_ANIMATION,
- * this shouldn't show up in 3D editor (or others without 2D timeline view) via search
- */
- if (sa) {
- if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_SEQ, SPACE_CLIP)) {
- return true;
- }
- else if (sa->spacetype == SPACE_GRAPH) {
- /* NOTE: Graph Editor has special version which does some extra stuff.
- * No need to show the generic error message for that case though!
- */
- return false;
- }
- }
-
- CTX_wm_operator_poll_msg_set(C, "Expected an animation area to be active");
- return false;
+ ScrArea *sa = CTX_wm_area(C);
+
+ /* XXX temp? prevent changes during render */
+ if (G.is_rendering)
+ return false;
+
+ /* although it's only included in keymaps for regions using ED_KEYMAP_ANIMATION,
+ * this shouldn't show up in 3D editor (or others without 2D timeline view) via search
+ */
+ if (sa) {
+ if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_NLA, SPACE_SEQ, SPACE_CLIP)) {
+ return true;
+ }
+ else if (sa->spacetype == SPACE_GRAPH) {
+ /* NOTE: Graph Editor has special version which does some extra stuff.
+ * No need to show the generic error message for that case though!
+ */
+ return false;
+ }
+ }
+
+ CTX_wm_operator_poll_msg_set(C, "Expected an animation area to be active");
+ return false;
}
/* Set the new frame number */
static void change_frame_apply(bContext *C, wmOperator *op)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- float frame = RNA_float_get(op->ptr, "frame");
- bool do_snap = RNA_boolean_get(op->ptr, "snap");
-
- if (do_snap) {
- if (CTX_wm_space_seq(C)) {
- frame = BKE_sequencer_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false);
- }
- else {
- frame = BKE_scene_frame_snap_by_seconds(scene, 1.0, frame);
- }
- }
-
- /* set the new frame number */
- if (scene->r.flag & SCER_SHOW_SUBFRAME) {
- CFRA = (int)frame;
- SUBFRA = frame - (int)frame;
- }
- else {
- CFRA = round_fl_to_int(frame);
- SUBFRA = 0.0f;
- }
- FRAMENUMBER_MIN_CLAMP(CFRA);
-
- /* do updates */
- BKE_sound_seek_scene(bmain, scene);
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ float frame = RNA_float_get(op->ptr, "frame");
+ bool do_snap = RNA_boolean_get(op->ptr, "snap");
+
+ if (do_snap) {
+ if (CTX_wm_space_seq(C)) {
+ frame = BKE_sequencer_find_next_prev_edit(scene, frame, SEQ_SIDE_BOTH, true, false, false);
+ }
+ else {
+ frame = BKE_scene_frame_snap_by_seconds(scene, 1.0, frame);
+ }
+ }
+
+ /* set the new frame number */
+ if (scene->r.flag & SCER_SHOW_SUBFRAME) {
+ CFRA = (int)frame;
+ SUBFRA = frame - (int)frame;
+ }
+ else {
+ CFRA = round_fl_to_int(frame);
+ SUBFRA = 0.0f;
+ }
+ FRAMENUMBER_MIN_CLAMP(CFRA);
+
+ /* do updates */
+ BKE_sound_seek_scene(bmain, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
}
/* ---- */
@@ -122,9 +122,9 @@ static void change_frame_apply(bContext *C, wmOperator *op)
/* Non-modal callback for running operator without user input */
static int change_frame_exec(bContext *C, wmOperator *op)
{
- change_frame_apply(C, op);
+ change_frame_apply(C, op);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
/* ---- */
@@ -132,402 +132,401 @@ static int change_frame_exec(bContext *C, wmOperator *op)
/* Get frame from mouse coordinates */
static float frame_from_event(bContext *C, const wmEvent *event)
{
- ARegion *region = CTX_wm_region(C);
- Scene *scene = CTX_data_scene(C);
- float frame;
+ ARegion *region = CTX_wm_region(C);
+ Scene *scene = CTX_data_scene(C);
+ float frame;
- /* convert from region coordinates to View2D 'tot' space */
- frame = UI_view2d_region_to_view_x(&region->v2d, event->mval[0]);
+ /* convert from region coordinates to View2D 'tot' space */
+ frame = UI_view2d_region_to_view_x(&region->v2d, event->mval[0]);
- /* respect preview range restrictions (if only allowed to move around within that range) */
- if (scene->r.flag & SCER_LOCK_FRAME_SELECTION) {
- CLAMP(frame, PSFRA, PEFRA);
- }
+ /* respect preview range restrictions (if only allowed to move around within that range) */
+ if (scene->r.flag & SCER_LOCK_FRAME_SELECTION) {
+ CLAMP(frame, PSFRA, PEFRA);
+ }
- return frame;
+ return frame;
}
static void change_frame_seq_preview_begin(bContext *C, const wmEvent *event)
{
- ScrArea *sa = CTX_wm_area(C);
- bScreen *screen = CTX_wm_screen(C);
- if (sa && sa->spacetype == SPACE_SEQ) {
- SpaceSeq *sseq = sa->spacedata.first;
- if (ED_space_sequencer_check_show_strip(sseq)) {
- ED_sequencer_special_preview_set(C, event->mval);
- }
- }
- if (screen)
- screen->scrubbing = true;
+ ScrArea *sa = CTX_wm_area(C);
+ bScreen *screen = CTX_wm_screen(C);
+ if (sa && sa->spacetype == SPACE_SEQ) {
+ SpaceSeq *sseq = sa->spacedata.first;
+ if (ED_space_sequencer_check_show_strip(sseq)) {
+ ED_sequencer_special_preview_set(C, event->mval);
+ }
+ }
+ if (screen)
+ screen->scrubbing = true;
}
static void change_frame_seq_preview_end(bContext *C)
{
- bScreen *screen = CTX_wm_screen(C);
- bool notify = false;
-
- if (screen->scrubbing) {
- screen->scrubbing = false;
- notify = true;
- }
-
- if (ED_sequencer_special_preview_get() != NULL) {
- ED_sequencer_special_preview_clear();
- notify = true;
- }
-
- if (notify) {
- Scene *scene = CTX_data_scene(C);
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
- }
+ bScreen *screen = CTX_wm_screen(C);
+ bool notify = false;
+
+ if (screen->scrubbing) {
+ screen->scrubbing = false;
+ notify = true;
+ }
+
+ if (ED_sequencer_special_preview_get() != NULL) {
+ ED_sequencer_special_preview_clear();
+ notify = true;
+ }
+
+ if (notify) {
+ Scene *scene = CTX_data_scene(C);
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ }
}
/* Modal Operator init */
static int change_frame_invoke(bContext *C, wmOperator *op, const wmEvent *event)
{
- /* Change to frame that mouse is over before adding modal handler,
- * as user could click on a single frame (jump to frame) as well as
- * click-dragging over a range (modal scrubbing).
- */
- RNA_float_set(op->ptr, "frame", frame_from_event(C, event));
+ /* Change to frame that mouse is over before adding modal handler,
+ * as user could click on a single frame (jump to frame) as well as
+ * click-dragging over a range (modal scrubbing).
+ */
+ RNA_float_set(op->ptr, "frame", frame_from_event(C, event));
- change_frame_seq_preview_begin(C, event);
+ change_frame_seq_preview_begin(C, event);
- change_frame_apply(C, op);
+ change_frame_apply(C, op);
- /* add temp handler */
- WM_event_add_modal_handler(C, op);
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
- return OPERATOR_RUNNING_MODAL;
+ return OPERATOR_RUNNING_MODAL;
}
static void change_frame_cancel(bContext *C, wmOperator *UNUSED(op))
{
- change_frame_seq_preview_end(C);
+ change_frame_seq_preview_end(C);
}
/* Modal event handling of frame changing */
static int change_frame_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
- int ret = OPERATOR_RUNNING_MODAL;
- /* execute the events */
- switch (event->type) {
- case ESCKEY:
- ret = OPERATOR_FINISHED;
- break;
-
- case MOUSEMOVE:
- RNA_float_set(op->ptr, "frame", frame_from_event(C, event));
- change_frame_apply(C, op);
- break;
-
- case LEFTMOUSE:
- case RIGHTMOUSE:
- case MIDDLEMOUSE:
- /* We check for either mouse-button to end, to work with all user keymaps. */
- if (event->val == KM_RELEASE)
- ret = OPERATOR_FINISHED;
- break;
-
- case LEFTCTRLKEY:
- case RIGHTCTRLKEY:
- if (event->val == KM_RELEASE) {
- RNA_boolean_set(op->ptr, "snap", false);
- }
- else if (event->val == KM_PRESS) {
- RNA_boolean_set(op->ptr, "snap", true);
- }
- break;
- }
-
- if (ret != OPERATOR_RUNNING_MODAL) {
- change_frame_seq_preview_end(C);
- }
-
- return ret;
+ int ret = OPERATOR_RUNNING_MODAL;
+ /* execute the events */
+ switch (event->type) {
+ case ESCKEY:
+ ret = OPERATOR_FINISHED;
+ break;
+
+ case MOUSEMOVE:
+ RNA_float_set(op->ptr, "frame", frame_from_event(C, event));
+ change_frame_apply(C, op);
+ break;
+
+ case LEFTMOUSE:
+ case RIGHTMOUSE:
+ case MIDDLEMOUSE:
+ /* We check for either mouse-button to end, to work with all user keymaps. */
+ if (event->val == KM_RELEASE)
+ ret = OPERATOR_FINISHED;
+ break;
+
+ case LEFTCTRLKEY:
+ case RIGHTCTRLKEY:
+ if (event->val == KM_RELEASE) {
+ RNA_boolean_set(op->ptr, "snap", false);
+ }
+ else if (event->val == KM_PRESS) {
+ RNA_boolean_set(op->ptr, "snap", true);
+ }
+ break;
+ }
+
+ if (ret != OPERATOR_RUNNING_MODAL) {
+ change_frame_seq_preview_end(C);
+ }
+
+ return ret;
}
static void ANIM_OT_change_frame(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Change Frame";
- ot->idname = "ANIM_OT_change_frame";
- ot->description = "Interactively change the current frame number";
-
- /* api callbacks */
- ot->exec = change_frame_exec;
- ot->invoke = change_frame_invoke;
- ot->cancel = change_frame_cancel;
- ot->modal = change_frame_modal;
- ot->poll = change_frame_poll;
-
- /* flags */
- ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR | OPTYPE_UNDO_GROUPED;
- ot->undo_group = "Frame Change";
-
- /* rna */
- ot->prop = RNA_def_float(ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
- prop = RNA_def_boolean(ot->srna, "snap", false, "Snap", "");
- RNA_def_property_flag(prop, PROP_SKIP_SAVE);
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Change Frame";
+ ot->idname = "ANIM_OT_change_frame";
+ ot->description = "Interactively change the current frame number";
+
+ /* api callbacks */
+ ot->exec = change_frame_exec;
+ ot->invoke = change_frame_invoke;
+ ot->cancel = change_frame_cancel;
+ ot->modal = change_frame_modal;
+ ot->poll = change_frame_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_GRAB_CURSOR | OPTYPE_UNDO_GROUPED;
+ ot->undo_group = "Frame Change";
+
+ /* rna */
+ ot->prop = RNA_def_float(
+ ot->srna, "frame", 0, MINAFRAME, MAXFRAME, "Frame", "", MINAFRAME, MAXFRAME);
+ prop = RNA_def_boolean(ot->srna, "snap", false, "Snap", "");
+ RNA_def_property_flag(prop, PROP_SKIP_SAVE);
}
-
/* ****************** Start/End Frame Operators *******************************/
static bool anim_set_end_frames_poll(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
-
- /* XXX temp? prevent changes during render */
- if (G.is_rendering) return false;
-
- /* although it's only included in keymaps for regions using ED_KEYMAP_ANIMATION,
- * this shouldn't show up in 3D editor (or others without 2D timeline view) via search
- */
- if (sa) {
- if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA, SPACE_SEQ, SPACE_CLIP)) {
- return true;
- }
- }
-
- CTX_wm_operator_poll_msg_set(C, "Expected an animation area to be active");
- return false;
+ ScrArea *sa = CTX_wm_area(C);
+
+ /* XXX temp? prevent changes during render */
+ if (G.is_rendering)
+ return false;
+
+ /* although it's only included in keymaps for regions using ED_KEYMAP_ANIMATION,
+ * this shouldn't show up in 3D editor (or others without 2D timeline view) via search
+ */
+ if (sa) {
+ if (ELEM(sa->spacetype, SPACE_ACTION, SPACE_GRAPH, SPACE_NLA, SPACE_SEQ, SPACE_CLIP)) {
+ return true;
+ }
+ }
+
+ CTX_wm_operator_poll_msg_set(C, "Expected an animation area to be active");
+ return false;
}
static int anim_set_sfra_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- int frame;
+ Scene *scene = CTX_data_scene(C);
+ int frame;
- if (scene == NULL)
- return OPERATOR_CANCELLED;
+ if (scene == NULL)
+ return OPERATOR_CANCELLED;
- frame = CFRA;
+ frame = CFRA;
- /* if Preview Range is defined, set the 'start' frame for that */
- if (PRVRANGEON)
- scene->r.psfra = frame;
- else
- scene->r.sfra = frame;
+ /* if Preview Range is defined, set the 'start' frame for that */
+ if (PRVRANGEON)
+ scene->r.psfra = frame;
+ else
+ scene->r.sfra = frame;
- if (PEFRA < frame) {
- if (PRVRANGEON)
- scene->r.pefra = frame;
- else
- scene->r.efra = frame;
- }
+ if (PEFRA < frame) {
+ if (PRVRANGEON)
+ scene->r.pefra = frame;
+ else
+ scene->r.efra = frame;
+ }
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_start_frame_set(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Start Frame";
- ot->idname = "ANIM_OT_start_frame_set";
- ot->description = "Set the current frame as the preview or scene start frame";
+ /* identifiers */
+ ot->name = "Set Start Frame";
+ ot->idname = "ANIM_OT_start_frame_set";
+ ot->description = "Set the current frame as the preview or scene start frame";
- /* api callbacks */
- ot->exec = anim_set_sfra_exec;
- ot->poll = anim_set_end_frames_poll;
+ /* api callbacks */
+ ot->exec = anim_set_sfra_exec;
+ ot->poll = anim_set_end_frames_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
static int anim_set_efra_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- int frame;
+ Scene *scene = CTX_data_scene(C);
+ int frame;
- if (scene == NULL)
- return OPERATOR_CANCELLED;
+ if (scene == NULL)
+ return OPERATOR_CANCELLED;
- frame = CFRA;
+ frame = CFRA;
- /* if Preview Range is defined, set the 'end' frame for that */
- if (PRVRANGEON)
- scene->r.pefra = frame;
- else
- scene->r.efra = frame;
+ /* if Preview Range is defined, set the 'end' frame for that */
+ if (PRVRANGEON)
+ scene->r.pefra = frame;
+ else
+ scene->r.efra = frame;
- if (PSFRA > frame) {
- if (PRVRANGEON)
- scene->r.psfra = frame;
- else
- scene->r.sfra = frame;
- }
+ if (PSFRA > frame) {
+ if (PRVRANGEON)
+ scene->r.psfra = frame;
+ else
+ scene->r.sfra = frame;
+ }
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_end_frame_set(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set End Frame";
- ot->idname = "ANIM_OT_end_frame_set";
- ot->description = "Set the current frame as the preview or scene end frame";
+ /* identifiers */
+ ot->name = "Set End Frame";
+ ot->idname = "ANIM_OT_end_frame_set";
+ ot->description = "Set the current frame as the preview or scene end frame";
- /* api callbacks */
- ot->exec = anim_set_efra_exec;
- ot->poll = anim_set_end_frames_poll;
+ /* api callbacks */
+ ot->exec = anim_set_efra_exec;
+ ot->poll = anim_set_end_frames_poll;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ****************** set preview range operator ****************************/
static int previewrange_define_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- ARegion *ar = CTX_wm_region(C);
- float sfra, efra;
- rcti rect;
-
- /* get min/max values from box select rect (already in region coordinates, not screen) */
- WM_operator_properties_border_to_rcti(op, &rect);
-
- /* convert min/max values to frames (i.e. region to 'tot' rect) */
- sfra = UI_view2d_region_to_view_x(&ar->v2d, rect.xmin);
- efra = UI_view2d_region_to_view_x(&ar->v2d, rect.xmax);
-
- /* set start/end frames for preview-range
- * - must clamp within allowable limits
- * - end must not be before start (though this won't occur most of the time)
- */
- FRAMENUMBER_MIN_CLAMP(sfra);
- FRAMENUMBER_MIN_CLAMP(efra);
- if (efra < sfra) efra = sfra;
-
- scene->r.flag |= SCER_PRV_RANGE;
- scene->r.psfra = round_fl_to_int(sfra);
- scene->r.pefra = round_fl_to_int(efra);
-
- /* send notifiers */
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
-
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ ARegion *ar = CTX_wm_region(C);
+ float sfra, efra;
+ rcti rect;
+
+ /* get min/max values from box select rect (already in region coordinates, not screen) */
+ WM_operator_properties_border_to_rcti(op, &rect);
+
+ /* convert min/max values to frames (i.e. region to 'tot' rect) */
+ sfra = UI_view2d_region_to_view_x(&ar->v2d, rect.xmin);
+ efra = UI_view2d_region_to_view_x(&ar->v2d, rect.xmax);
+
+ /* set start/end frames for preview-range
+ * - must clamp within allowable limits
+ * - end must not be before start (though this won't occur most of the time)
+ */
+ FRAMENUMBER_MIN_CLAMP(sfra);
+ FRAMENUMBER_MIN_CLAMP(efra);
+ if (efra < sfra)
+ efra = sfra;
+
+ scene->r.flag |= SCER_PRV_RANGE;
+ scene->r.psfra = round_fl_to_int(sfra);
+ scene->r.pefra = round_fl_to_int(efra);
+
+ /* send notifiers */
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_previewrange_set(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Set Preview Range";
- ot->idname = "ANIM_OT_previewrange_set";
- ot->description = "Interactively define frame range used for playback";
-
- /* api callbacks */
- ot->invoke = WM_gesture_box_invoke;
- ot->exec = previewrange_define_exec;
- ot->modal = WM_gesture_box_modal;
- ot->cancel = WM_gesture_box_cancel;
-
- ot->poll = ED_operator_animview_active;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* rna */
- /* used to define frame range.
- *
- * note: border Y values are not used,
- * but are needed by box_select gesture operator stuff */
- WM_operator_properties_border(ot);
+ /* identifiers */
+ ot->name = "Set Preview Range";
+ ot->idname = "ANIM_OT_previewrange_set";
+ ot->description = "Interactively define frame range used for playback";
+
+ /* api callbacks */
+ ot->invoke = WM_gesture_box_invoke;
+ ot->exec = previewrange_define_exec;
+ ot->modal = WM_gesture_box_modal;
+ ot->cancel = WM_gesture_box_cancel;
+
+ ot->poll = ED_operator_animview_active;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* rna */
+ /* used to define frame range.
+ *
+ * note: border Y values are not used,
+ * but are needed by box_select gesture operator stuff */
+ WM_operator_properties_border(ot);
}
/* ****************** clear preview range operator ****************************/
static int previewrange_clear_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- ScrArea *curarea = CTX_wm_area(C);
+ Scene *scene = CTX_data_scene(C);
+ ScrArea *curarea = CTX_wm_area(C);
- /* sanity checks */
- if (ELEM(NULL, scene, curarea))
- return OPERATOR_CANCELLED;
+ /* sanity checks */
+ if (ELEM(NULL, scene, curarea))
+ return OPERATOR_CANCELLED;
- /* simply clear values */
- scene->r.flag &= ~SCER_PRV_RANGE;
- scene->r.psfra = 0;
- scene->r.pefra = 0;
+ /* simply clear values */
+ scene->r.flag &= ~SCER_PRV_RANGE;
+ scene->r.psfra = 0;
+ scene->r.pefra = 0;
- ED_area_tag_redraw(curarea);
+ ED_area_tag_redraw(curarea);
- /* send notifiers */
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
+ /* send notifiers */
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
static void ANIM_OT_previewrange_clear(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Clear Preview Range";
- ot->idname = "ANIM_OT_previewrange_clear";
- ot->description = "Clear Preview Range";
+ /* identifiers */
+ ot->name = "Clear Preview Range";
+ ot->idname = "ANIM_OT_previewrange_clear";
+ ot->description = "Clear Preview Range";
- /* api callbacks */
- ot->exec = previewrange_clear_exec;
+ /* api callbacks */
+ ot->exec = previewrange_clear_exec;
- ot->poll = ED_operator_animview_active;
+ ot->poll = ED_operator_animview_active;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ************************** registration **********************************/
void ED_operatortypes_anim(void)
{
- /* Animation Editors only -------------------------- */
- WM_operatortype_append(ANIM_OT_change_frame);
-
- WM_operatortype_append(ANIM_OT_start_frame_set);
- WM_operatortype_append(ANIM_OT_end_frame_set);
-
- WM_operatortype_append(ANIM_OT_previewrange_set);
- WM_operatortype_append(ANIM_OT_previewrange_clear);
-
- /* Entire UI --------------------------------------- */
- WM_operatortype_append(ANIM_OT_keyframe_insert);
- WM_operatortype_append(ANIM_OT_keyframe_delete);
- WM_operatortype_append(ANIM_OT_keyframe_insert_menu);
- WM_operatortype_append(ANIM_OT_keyframe_delete_v3d);
- WM_operatortype_append(ANIM_OT_keyframe_clear_v3d);
- WM_operatortype_append(ANIM_OT_keyframe_insert_button);
- WM_operatortype_append(ANIM_OT_keyframe_delete_button);
- WM_operatortype_append(ANIM_OT_keyframe_clear_button);
- WM_operatortype_append(ANIM_OT_keyframe_insert_by_name);
- WM_operatortype_append(ANIM_OT_keyframe_delete_by_name);
-
-
- WM_operatortype_append(ANIM_OT_driver_button_add);
- WM_operatortype_append(ANIM_OT_driver_button_remove);
- WM_operatortype_append(ANIM_OT_driver_button_edit);
- WM_operatortype_append(ANIM_OT_copy_driver_button);
- WM_operatortype_append(ANIM_OT_paste_driver_button);
-
-
- WM_operatortype_append(ANIM_OT_keyingset_button_add);
- WM_operatortype_append(ANIM_OT_keyingset_button_remove);
-
- WM_operatortype_append(ANIM_OT_keying_set_add);
- WM_operatortype_append(ANIM_OT_keying_set_remove);
- WM_operatortype_append(ANIM_OT_keying_set_path_add);
- WM_operatortype_append(ANIM_OT_keying_set_path_remove);
-
- WM_operatortype_append(ANIM_OT_keying_set_active_set);
+ /* Animation Editors only -------------------------- */
+ WM_operatortype_append(ANIM_OT_change_frame);
+
+ WM_operatortype_append(ANIM_OT_start_frame_set);
+ WM_operatortype_append(ANIM_OT_end_frame_set);
+
+ WM_operatortype_append(ANIM_OT_previewrange_set);
+ WM_operatortype_append(ANIM_OT_previewrange_clear);
+
+ /* Entire UI --------------------------------------- */
+ WM_operatortype_append(ANIM_OT_keyframe_insert);
+ WM_operatortype_append(ANIM_OT_keyframe_delete);
+ WM_operatortype_append(ANIM_OT_keyframe_insert_menu);
+ WM_operatortype_append(ANIM_OT_keyframe_delete_v3d);
+ WM_operatortype_append(ANIM_OT_keyframe_clear_v3d);
+ WM_operatortype_append(ANIM_OT_keyframe_insert_button);
+ WM_operatortype_append(ANIM_OT_keyframe_delete_button);
+ WM_operatortype_append(ANIM_OT_keyframe_clear_button);
+ WM_operatortype_append(ANIM_OT_keyframe_insert_by_name);
+ WM_operatortype_append(ANIM_OT_keyframe_delete_by_name);
+
+ WM_operatortype_append(ANIM_OT_driver_button_add);
+ WM_operatortype_append(ANIM_OT_driver_button_remove);
+ WM_operatortype_append(ANIM_OT_driver_button_edit);
+ WM_operatortype_append(ANIM_OT_copy_driver_button);
+ WM_operatortype_append(ANIM_OT_paste_driver_button);
+
+ WM_operatortype_append(ANIM_OT_keyingset_button_add);
+ WM_operatortype_append(ANIM_OT_keyingset_button_remove);
+
+ WM_operatortype_append(ANIM_OT_keying_set_add);
+ WM_operatortype_append(ANIM_OT_keying_set_remove);
+ WM_operatortype_append(ANIM_OT_keying_set_path_add);
+ WM_operatortype_append(ANIM_OT_keying_set_path_remove);
+
+ WM_operatortype_append(ANIM_OT_keying_set_active_set);
}
void ED_keymap_anim(wmKeyConfig *keyconf)
{
- WM_keymap_ensure(keyconf, "Animation", 0, 0);
+ WM_keymap_ensure(keyconf, "Animation", 0, 0);
}
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index d726c25816b..d6564be9574 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
#include <stdio.h>
#include <string.h>
@@ -70,212 +69,216 @@
*/
FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_index, short add)
{
- AnimData *adt;
- FCurve *fcu;
-
- /* sanity checks */
- if (ELEM(NULL, id, rna_path))
- return NULL;
-
- /* init animdata if none available yet */
- adt = BKE_animdata_from_id(id);
- if ((adt == NULL) && (add))
- adt = BKE_animdata_add_id(id);
- if (adt == NULL) {
- /* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
- return NULL;
- }
-
- /* try to find f-curve matching for this setting
- * - add if not found and allowed to add one
- * TODO: add auto-grouping support? how this works will need to be resolved
- */
- fcu = list_find_fcurve(&adt->drivers, rna_path, array_index);
-
- if ((fcu == NULL) && (add)) {
- /* use default settings to make a F-Curve */
- fcu = MEM_callocN(sizeof(FCurve), "FCurve");
-
- fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
- fcu->auto_smoothing = FCURVE_SMOOTH_CONT_ACCEL;
-
- /* store path - make copy, and store that */
- fcu->rna_path = BLI_strdup(rna_path);
- fcu->array_index = array_index;
-
- /* if add is negative, don't init this data yet, since it will be filled in by the pasted driver */
- if (add > 0) {
- BezTriple *bezt;
- size_t i;
-
- /* add some new driver data */
- fcu->driver = MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
-
- /* F-Modifier or Keyframes? */
- // FIXME: replace these magic numbers with defines
- if (add == 2) {
- /* Python API Backwards compatibility hack:
- * Create FModifier so that old scripts won't break
- * for now before 2.7 series -- (September 4, 2013)
- */
- add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR, fcu);
- }
- else {
- /* add 2 keyframes so that user has something to work with
- * - These are configured to 0,0 and 1,1 to give a 1-1 mapping
- * which can be easily tweaked from there.
- */
- insert_vert_fcurve(fcu, 0.0f, 0.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST);
- insert_vert_fcurve(fcu, 1.0f, 1.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST);
-
- /* configure this curve to extrapolate */
- for (i = 0, bezt = fcu->bezt; (i < fcu->totvert) && bezt; i++, bezt++) {
- bezt->h1 = bezt->h2 = HD_VECT;
- }
-
- fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
- calchandles_fcurve(fcu);
- }
- }
-
- /* just add F-Curve to end of driver list */
- BLI_addtail(&adt->drivers, fcu);
- }
-
- /* return the F-Curve */
- return fcu;
+ AnimData *adt;
+ FCurve *fcu;
+
+ /* sanity checks */
+ if (ELEM(NULL, id, rna_path))
+ return NULL;
+
+ /* init animdata if none available yet */
+ adt = BKE_animdata_from_id(id);
+ if ((adt == NULL) && (add))
+ adt = BKE_animdata_add_id(id);
+ if (adt == NULL) {
+ /* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
+ return NULL;
+ }
+
+ /* try to find f-curve matching for this setting
+ * - add if not found and allowed to add one
+ * TODO: add auto-grouping support? how this works will need to be resolved
+ */
+ fcu = list_find_fcurve(&adt->drivers, rna_path, array_index);
+
+ if ((fcu == NULL) && (add)) {
+ /* use default settings to make a F-Curve */
+ fcu = MEM_callocN(sizeof(FCurve), "FCurve");
+
+ fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
+ fcu->auto_smoothing = FCURVE_SMOOTH_CONT_ACCEL;
+
+ /* store path - make copy, and store that */
+ fcu->rna_path = BLI_strdup(rna_path);
+ fcu->array_index = array_index;
+
+ /* if add is negative, don't init this data yet, since it will be filled in by the pasted driver */
+ if (add > 0) {
+ BezTriple *bezt;
+ size_t i;
+
+ /* add some new driver data */
+ fcu->driver = MEM_callocN(sizeof(ChannelDriver), "ChannelDriver");
+
+ /* F-Modifier or Keyframes? */
+ // FIXME: replace these magic numbers with defines
+ if (add == 2) {
+ /* Python API Backwards compatibility hack:
+ * Create FModifier so that old scripts won't break
+ * for now before 2.7 series -- (September 4, 2013)
+ */
+ add_fmodifier(&fcu->modifiers, FMODIFIER_TYPE_GENERATOR, fcu);
+ }
+ else {
+ /* add 2 keyframes so that user has something to work with
+ * - These are configured to 0,0 and 1,1 to give a 1-1 mapping
+ * which can be easily tweaked from there.
+ */
+ insert_vert_fcurve(fcu, 0.0f, 0.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST);
+ insert_vert_fcurve(fcu, 1.0f, 1.0f, BEZT_KEYTYPE_KEYFRAME, INSERTKEY_FAST);
+
+ /* configure this curve to extrapolate */
+ for (i = 0, bezt = fcu->bezt; (i < fcu->totvert) && bezt; i++, bezt++) {
+ bezt->h1 = bezt->h2 = HD_VECT;
+ }
+
+ fcu->extend = FCURVE_EXTRAPOLATE_LINEAR;
+ calchandles_fcurve(fcu);
+ }
+ }
+
+ /* just add F-Curve to end of driver list */
+ BLI_addtail(&adt->drivers, fcu);
+ }
+
+ /* return the F-Curve */
+ return fcu;
}
/* ************************************************** */
/* Driver Management API */
/* Helper for ANIM_add_driver_with_target - Adds the actual driver */
-static int add_driver_with_target(
- ReportList *UNUSED(reports),
- ID *dst_id, const char dst_path[], int dst_index,
- ID *src_id, const char src_path[], int src_index,
- PointerRNA *dst_ptr, PropertyRNA *dst_prop,
- PointerRNA *src_ptr, PropertyRNA *src_prop,
- short flag, int driver_type)
+static int add_driver_with_target(ReportList *UNUSED(reports),
+ ID *dst_id,
+ const char dst_path[],
+ int dst_index,
+ ID *src_id,
+ const char src_path[],
+ int src_index,
+ PointerRNA *dst_ptr,
+ PropertyRNA *dst_prop,
+ PointerRNA *src_ptr,
+ PropertyRNA *src_prop,
+ short flag,
+ int driver_type)
{
- FCurve *fcu;
- short add_mode = (flag & CREATEDRIVER_WITH_FMODIFIER) ? 2 : 1;
- const char *prop_name = RNA_property_identifier(src_prop);
-
- /* Create F-Curve with Driver */
- fcu = verify_driver_fcurve(dst_id, dst_path, dst_index, add_mode);
-
- if (fcu && fcu->driver) {
- ChannelDriver *driver = fcu->driver;
- DriverVar *dvar;
-
- /* Set the type of the driver */
- driver->type = driver_type;
-
- /* Set driver expression, so that the driver works out of the box
- *
- * The following checks define a bit of "autodetection magic" we use
- * to ensure that the drivers will behave as expected out of the box
- * when faced with properties with different units.
- */
- /* XXX: if we have N-1 mapping, should we include all those in the expression? */
- if ((RNA_property_unit(dst_prop) == PROP_UNIT_ROTATION) &&
- (RNA_property_unit(src_prop) != PROP_UNIT_ROTATION))
- {
- /* Rotation Destination: normal -> radians, so convert src to radians
- * (However, if both input and output is a rotation, don't apply such corrections)
- */
- BLI_strncpy(driver->expression, "radians(var)", sizeof(driver->expression));
- }
- else if ((RNA_property_unit(src_prop) == PROP_UNIT_ROTATION) &&
- (RNA_property_unit(dst_prop) != PROP_UNIT_ROTATION))
- {
- /* Rotation Source: radians -> normal, so convert src to degrees
- * (However, if both input and output is a rotation, don't apply such corrections)
- */
- BLI_strncpy(driver->expression, "degrees(var)", sizeof(driver->expression));
- }
- else {
- /* Just a normal property without any unit problems */
- BLI_strncpy(driver->expression, "var", sizeof(driver->expression));
- }
-
- /* Create a driver variable for the target
- * - For transform properties, we want to automatically use "transform channel" instead
- * (The only issue is with quat rotations vs euler channels...)
- * - To avoid problems with transform properties depending on the final transform that they
- * control (thus creating pseudo-cycles - see T48734), we don't use transform channels
- * when both the source and destinations are in same places.
- */
- dvar = driver_add_new_variable(driver);
-
- if (ELEM(src_ptr->type, &RNA_Object, &RNA_PoseBone) &&
- (STREQ(prop_name, "location") || STREQ(prop_name, "scale") || STRPREFIX(prop_name, "rotation_")) &&
- (src_ptr->data != dst_ptr->data))
- {
- /* Transform Channel */
- DriverTarget *dtar;
-
- driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
- dtar = &dvar->targets[0];
-
- /* Bone or Object target? */
- dtar->id = src_id;
- dtar->idtype = GS(src_id->name);
-
- if (src_ptr->type == &RNA_PoseBone) {
- RNA_string_get(src_ptr, "name", dtar->pchan_name);
- }
-
- /* Transform channel depends on type */
- if (STREQ(prop_name, "location")) {
- if (src_index == 2)
- dtar->transChan = DTAR_TRANSCHAN_LOCZ;
- else if (src_index == 1)
- dtar->transChan = DTAR_TRANSCHAN_LOCY;
- else
- dtar->transChan = DTAR_TRANSCHAN_LOCX;
- }
- else if (STREQ(prop_name, "scale")) {
- if (src_index == 2)
- dtar->transChan = DTAR_TRANSCHAN_SCALEZ;
- else if (src_index == 1)
- dtar->transChan = DTAR_TRANSCHAN_SCALEY;
- else
- dtar->transChan = DTAR_TRANSCHAN_SCALEX;
- }
- else {
- /* XXX: With quaternions and axis-angle, this mapping might not be correct...
- * But since those have 4 elements instead, there's not much we can do
- */
- if (src_index == 2)
- dtar->transChan = DTAR_TRANSCHAN_ROTZ;
- else if (src_index == 1)
- dtar->transChan = DTAR_TRANSCHAN_ROTY;
- else
- dtar->transChan = DTAR_TRANSCHAN_ROTX;
- }
- }
- else {
- /* Single RNA Property */
- DriverTarget *dtar = &dvar->targets[0];
-
- /* ID is as-is */
- dtar->id = src_id;
- dtar->idtype = GS(src_id->name);
-
- /* Need to make a copy of the path (or build one with array index built in) */
- if (RNA_property_array_check(src_prop)) {
- dtar->rna_path = BLI_sprintfN("%s[%d]", src_path, src_index);
- }
- else {
- dtar->rna_path = BLI_strdup(src_path);
- }
- }
- }
-
- /* set the done status */
- return (fcu != NULL);
+ FCurve *fcu;
+ short add_mode = (flag & CREATEDRIVER_WITH_FMODIFIER) ? 2 : 1;
+ const char *prop_name = RNA_property_identifier(src_prop);
+
+ /* Create F-Curve with Driver */
+ fcu = verify_driver_fcurve(dst_id, dst_path, dst_index, add_mode);
+
+ if (fcu && fcu->driver) {
+ ChannelDriver *driver = fcu->driver;
+ DriverVar *dvar;
+
+ /* Set the type of the driver */
+ driver->type = driver_type;
+
+ /* Set driver expression, so that the driver works out of the box
+ *
+ * The following checks define a bit of "autodetection magic" we use
+ * to ensure that the drivers will behave as expected out of the box
+ * when faced with properties with different units.
+ */
+ /* XXX: if we have N-1 mapping, should we include all those in the expression? */
+ if ((RNA_property_unit(dst_prop) == PROP_UNIT_ROTATION) &&
+ (RNA_property_unit(src_prop) != PROP_UNIT_ROTATION)) {
+ /* Rotation Destination: normal -> radians, so convert src to radians
+ * (However, if both input and output is a rotation, don't apply such corrections)
+ */
+ BLI_strncpy(driver->expression, "radians(var)", sizeof(driver->expression));
+ }
+ else if ((RNA_property_unit(src_prop) == PROP_UNIT_ROTATION) &&
+ (RNA_property_unit(dst_prop) != PROP_UNIT_ROTATION)) {
+ /* Rotation Source: radians -> normal, so convert src to degrees
+ * (However, if both input and output is a rotation, don't apply such corrections)
+ */
+ BLI_strncpy(driver->expression, "degrees(var)", sizeof(driver->expression));
+ }
+ else {
+ /* Just a normal property without any unit problems */
+ BLI_strncpy(driver->expression, "var", sizeof(driver->expression));
+ }
+
+ /* Create a driver variable for the target
+ * - For transform properties, we want to automatically use "transform channel" instead
+ * (The only issue is with quat rotations vs euler channels...)
+ * - To avoid problems with transform properties depending on the final transform that they
+ * control (thus creating pseudo-cycles - see T48734), we don't use transform channels
+ * when both the source and destinations are in same places.
+ */
+ dvar = driver_add_new_variable(driver);
+
+ if (ELEM(src_ptr->type, &RNA_Object, &RNA_PoseBone) &&
+ (STREQ(prop_name, "location") || STREQ(prop_name, "scale") ||
+ STRPREFIX(prop_name, "rotation_")) &&
+ (src_ptr->data != dst_ptr->data)) {
+ /* Transform Channel */
+ DriverTarget *dtar;
+
+ driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
+ dtar = &dvar->targets[0];
+
+ /* Bone or Object target? */
+ dtar->id = src_id;
+ dtar->idtype = GS(src_id->name);
+
+ if (src_ptr->type == &RNA_PoseBone) {
+ RNA_string_get(src_ptr, "name", dtar->pchan_name);
+ }
+
+ /* Transform channel depends on type */
+ if (STREQ(prop_name, "location")) {
+ if (src_index == 2)
+ dtar->transChan = DTAR_TRANSCHAN_LOCZ;
+ else if (src_index == 1)
+ dtar->transChan = DTAR_TRANSCHAN_LOCY;
+ else
+ dtar->transChan = DTAR_TRANSCHAN_LOCX;
+ }
+ else if (STREQ(prop_name, "scale")) {
+ if (src_index == 2)
+ dtar->transChan = DTAR_TRANSCHAN_SCALEZ;
+ else if (src_index == 1)
+ dtar->transChan = DTAR_TRANSCHAN_SCALEY;
+ else
+ dtar->transChan = DTAR_TRANSCHAN_SCALEX;
+ }
+ else {
+ /* XXX: With quaternions and axis-angle, this mapping might not be correct...
+ * But since those have 4 elements instead, there's not much we can do
+ */
+ if (src_index == 2)
+ dtar->transChan = DTAR_TRANSCHAN_ROTZ;
+ else if (src_index == 1)
+ dtar->transChan = DTAR_TRANSCHAN_ROTY;
+ else
+ dtar->transChan = DTAR_TRANSCHAN_ROTX;
+ }
+ }
+ else {
+ /* Single RNA Property */
+ DriverTarget *dtar = &dvar->targets[0];
+
+ /* ID is as-is */
+ dtar->id = src_id;
+ dtar->idtype = GS(src_id->name);
+
+ /* Need to make a copy of the path (or build one with array index built in) */
+ if (RNA_property_array_check(src_prop)) {
+ dtar->rna_path = BLI_sprintfN("%s[%d]", src_path, src_index);
+ }
+ else {
+ dtar->rna_path = BLI_strdup(src_path);
+ }
+ }
+ }
+
+ /* set the done status */
+ return (fcu != NULL);
}
/* Main Driver Management API calls:
@@ -289,75 +292,118 @@ static int add_driver_with_target(
* - driver_type: eDriver_Types
* - mapping_type: eCreateDriver_MappingTypes
*/
-int ANIM_add_driver_with_target(
- ReportList *reports,
- ID *dst_id, const char dst_path[], int dst_index,
- ID *src_id, const char src_path[], int src_index,
- short flag, int driver_type, short mapping_type)
+int ANIM_add_driver_with_target(ReportList *reports,
+ ID *dst_id,
+ const char dst_path[],
+ int dst_index,
+ ID *src_id,
+ const char src_path[],
+ int src_index,
+ short flag,
+ int driver_type,
+ short mapping_type)
{
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
-
- PointerRNA id_ptr2, ptr2;
- PropertyRNA *prop2;
- int done_tot = 0;
-
- /* validate pointers first - exit if failure */
- RNA_id_pointer_create(dst_id, &id_ptr);
- if (RNA_path_resolve_property(&id_ptr, dst_path, &ptr, &prop) == false) {
- BKE_reportf(reports, RPT_ERROR,
- "Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
- dst_id->name, dst_path);
- return 0;
- }
-
- RNA_id_pointer_create(src_id, &id_ptr2);
- if ((RNA_path_resolve_property(&id_ptr2, src_path, &ptr2, &prop2) == false) ||
- (mapping_type == CREATEDRIVER_MAPPING_NONE))
- {
- /* No target - So, fall back to default method for adding a "simple" driver normally */
- return ANIM_add_driver(reports, dst_id, dst_path, dst_index, flag | CREATEDRIVER_WITH_DEFAULT_DVAR, driver_type);
- }
-
- /* handle curve-property mappings based on mapping_type */
- switch (mapping_type) {
- case CREATEDRIVER_MAPPING_N_N: /* N-N - Try to match as much as possible,
- * then use the first one */
- {
- /* Use the shorter of the two (to avoid out of bounds access) */
- int dst_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
- int src_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr2, prop2) : 1;
-
- int len = MIN2(dst_len, src_len);
- int i;
-
- for (i = 0; i < len; i++) {
- done_tot += add_driver_with_target(reports, dst_id, dst_path, i, src_id, src_path, i, &ptr, prop, &ptr2, prop2, flag, driver_type);
- }
- break;
- }
-
- case CREATEDRIVER_MAPPING_1_N: /* 1-N - Specified target index for all */
- default:
- {
- int len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
- int i;
-
- for (i = 0; i < len; i++) {
- done_tot += add_driver_with_target(reports, dst_id, dst_path, i, src_id, src_path, src_index, &ptr, prop, &ptr2, prop2, flag, driver_type);
- }
- break;
- }
-
- case CREATEDRIVER_MAPPING_1_1: /* 1-1 - Use the specified index (unless -1) */
- {
- done_tot = add_driver_with_target(reports, dst_id, dst_path, dst_index, src_id, src_path, src_index, &ptr, prop, &ptr2, prop2, flag, driver_type);
- break;
- }
- }
-
- /* done */
- return done_tot;
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+
+ PointerRNA id_ptr2, ptr2;
+ PropertyRNA *prop2;
+ int done_tot = 0;
+
+ /* validate pointers first - exit if failure */
+ RNA_id_pointer_create(dst_id, &id_ptr);
+ if (RNA_path_resolve_property(&id_ptr, dst_path, &ptr, &prop) == false) {
+ BKE_reportf(
+ reports,
+ RPT_ERROR,
+ "Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
+ dst_id->name,
+ dst_path);
+ return 0;
+ }
+
+ RNA_id_pointer_create(src_id, &id_ptr2);
+ if ((RNA_path_resolve_property(&id_ptr2, src_path, &ptr2, &prop2) == false) ||
+ (mapping_type == CREATEDRIVER_MAPPING_NONE)) {
+ /* No target - So, fall back to default method for adding a "simple" driver normally */
+ return ANIM_add_driver(
+ reports, dst_id, dst_path, dst_index, flag | CREATEDRIVER_WITH_DEFAULT_DVAR, driver_type);
+ }
+
+ /* handle curve-property mappings based on mapping_type */
+ switch (mapping_type) {
+ case CREATEDRIVER_MAPPING_N_N: /* N-N - Try to match as much as possible,
+ * then use the first one */
+ {
+ /* Use the shorter of the two (to avoid out of bounds access) */
+ int dst_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
+ int src_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr2, prop2) : 1;
+
+ int len = MIN2(dst_len, src_len);
+ int i;
+
+ for (i = 0; i < len; i++) {
+ done_tot += add_driver_with_target(reports,
+ dst_id,
+ dst_path,
+ i,
+ src_id,
+ src_path,
+ i,
+ &ptr,
+ prop,
+ &ptr2,
+ prop2,
+ flag,
+ driver_type);
+ }
+ break;
+ }
+
+ case CREATEDRIVER_MAPPING_1_N: /* 1-N - Specified target index for all */
+ default: {
+ int len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ done_tot += add_driver_with_target(reports,
+ dst_id,
+ dst_path,
+ i,
+ src_id,
+ src_path,
+ src_index,
+ &ptr,
+ prop,
+ &ptr2,
+ prop2,
+ flag,
+ driver_type);
+ }
+ break;
+ }
+
+ case CREATEDRIVER_MAPPING_1_1: /* 1-1 - Use the specified index (unless -1) */
+ {
+ done_tot = add_driver_with_target(reports,
+ dst_id,
+ dst_path,
+ dst_index,
+ src_id,
+ src_path,
+ src_index,
+ &ptr,
+ prop,
+ &ptr2,
+ prop2,
+ flag,
+ driver_type);
+ break;
+ }
+ }
+
+ /* done */
+ return done_tot;
}
/* --------------------------------- */
@@ -365,155 +411,169 @@ int ANIM_add_driver_with_target(
/* Main Driver Management API calls:
* Add a new driver for the specified property on the given ID block
*/
-int ANIM_add_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short flag, int type)
+int ANIM_add_driver(
+ ReportList *reports, ID *id, const char rna_path[], int array_index, short flag, int type)
{
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
- FCurve *fcu;
- int array_index_max;
- int done_tot = 0;
-
- /* validate pointer first - exit if failure */
- RNA_id_pointer_create(id, &id_ptr);
- if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
- BKE_reportf(reports, RPT_ERROR,
- "Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
- id->name, rna_path);
- return 0;
- }
-
- /* key entire array convenience method */
- if (array_index == -1) {
- array_index_max = RNA_property_array_length(&ptr, prop);
- array_index = 0;
- }
- else
- array_index_max = array_index;
-
- /* maximum index should be greater than the start index */
- if (array_index == array_index_max)
- array_index_max += 1;
-
- /* will only loop once unless the array index was -1 */
- for (; array_index < array_index_max; array_index++) {
- short add_mode = (flag & CREATEDRIVER_WITH_FMODIFIER) ? 2 : 1;
-
- /* create F-Curve with Driver */
- fcu = verify_driver_fcurve(id, rna_path, array_index, add_mode);
-
- if (fcu && fcu->driver) {
- ChannelDriver *driver = fcu->driver;
-
- /* set the type of the driver */
- driver->type = type;
-
- /* Creating drivers for buttons will create the driver(s) with type
- * "scripted expression" so that their values won't be lost immediately,
- * so here we copy those values over to the driver's expression
- *
- * If the "default dvar" option (for easier UI setup of drivers) is provided,
- * include "var" in the expressions too, so that the user doesn't have to edit
- * it to get something to happen. It should be fine to just add it to the default
- * value, so that we get both in the expression, even if it's a bit more confusing
- * that way...
- */
- if (type == DRIVER_TYPE_PYTHON) {
- PropertyType proptype = RNA_property_type(prop);
- int array = RNA_property_array_length(&ptr, prop);
- const char *dvar_prefix = (flag & CREATEDRIVER_WITH_DEFAULT_DVAR) ? "var + " : "";
- char *expression = driver->expression;
- int val, maxlen = sizeof(driver->expression);
- float fval;
-
- if (proptype == PROP_BOOLEAN) {
- if (!array) val = RNA_property_boolean_get(&ptr, prop);
- else val = RNA_property_boolean_get_index(&ptr, prop, array_index);
-
- BLI_snprintf(expression, maxlen, "%s%s", dvar_prefix, (val) ? "True" : "False");
- }
- else if (proptype == PROP_INT) {
- if (!array) val = RNA_property_int_get(&ptr, prop);
- else val = RNA_property_int_get_index(&ptr, prop, array_index);
-
- BLI_snprintf(expression, maxlen, "%s%d", dvar_prefix, val);
- }
- else if (proptype == PROP_FLOAT) {
- if (!array) fval = RNA_property_float_get(&ptr, prop);
- else fval = RNA_property_float_get_index(&ptr, prop, array_index);
-
- BLI_snprintf(expression, maxlen, "%s%.3f", dvar_prefix, fval);
- BLI_str_rstrip_float_zero(expression, '\0');
- }
- else if (flag & CREATEDRIVER_WITH_DEFAULT_DVAR) {
- BLI_strncpy(expression, "var", maxlen);
- }
- }
-
- /* for easier setup of drivers from UI, a driver variable should be
- * added if flag is set (UI calls only)
- */
- if (flag & CREATEDRIVER_WITH_DEFAULT_DVAR) {
- /* assume that users will mostly want this to be of type "Transform Channel" too,
- * since this allows the easiest setting up of common rig components
- */
- DriverVar *dvar = driver_add_new_variable(driver);
- driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
- }
- }
-
- /* set the done status */
- done_tot += (fcu != NULL);
- }
-
- /* done */
- return done_tot;
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ FCurve *fcu;
+ int array_index_max;
+ int done_tot = 0;
+
+ /* validate pointer first - exit if failure */
+ RNA_id_pointer_create(id, &id_ptr);
+ if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
+ BKE_reportf(
+ reports,
+ RPT_ERROR,
+ "Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
+ id->name,
+ rna_path);
+ return 0;
+ }
+
+ /* key entire array convenience method */
+ if (array_index == -1) {
+ array_index_max = RNA_property_array_length(&ptr, prop);
+ array_index = 0;
+ }
+ else
+ array_index_max = array_index;
+
+ /* maximum index should be greater than the start index */
+ if (array_index == array_index_max)
+ array_index_max += 1;
+
+ /* will only loop once unless the array index was -1 */
+ for (; array_index < array_index_max; array_index++) {
+ short add_mode = (flag & CREATEDRIVER_WITH_FMODIFIER) ? 2 : 1;
+
+ /* create F-Curve with Driver */
+ fcu = verify_driver_fcurve(id, rna_path, array_index, add_mode);
+
+ if (fcu && fcu->driver) {
+ ChannelDriver *driver = fcu->driver;
+
+ /* set the type of the driver */
+ driver->type = type;
+
+ /* Creating drivers for buttons will create the driver(s) with type
+ * "scripted expression" so that their values won't be lost immediately,
+ * so here we copy those values over to the driver's expression
+ *
+ * If the "default dvar" option (for easier UI setup of drivers) is provided,
+ * include "var" in the expressions too, so that the user doesn't have to edit
+ * it to get something to happen. It should be fine to just add it to the default
+ * value, so that we get both in the expression, even if it's a bit more confusing
+ * that way...
+ */
+ if (type == DRIVER_TYPE_PYTHON) {
+ PropertyType proptype = RNA_property_type(prop);
+ int array = RNA_property_array_length(&ptr, prop);
+ const char *dvar_prefix = (flag & CREATEDRIVER_WITH_DEFAULT_DVAR) ? "var + " : "";
+ char *expression = driver->expression;
+ int val, maxlen = sizeof(driver->expression);
+ float fval;
+
+ if (proptype == PROP_BOOLEAN) {
+ if (!array)
+ val = RNA_property_boolean_get(&ptr, prop);
+ else
+ val = RNA_property_boolean_get_index(&ptr, prop, array_index);
+
+ BLI_snprintf(expression, maxlen, "%s%s", dvar_prefix, (val) ? "True" : "False");
+ }
+ else if (proptype == PROP_INT) {
+ if (!array)
+ val = RNA_property_int_get(&ptr, prop);
+ else
+ val = RNA_property_int_get_index(&ptr, prop, array_index);
+
+ BLI_snprintf(expression, maxlen, "%s%d", dvar_prefix, val);
+ }
+ else if (proptype == PROP_FLOAT) {
+ if (!array)
+ fval = RNA_property_float_get(&ptr, prop);
+ else
+ fval = RNA_property_float_get_index(&ptr, prop, array_index);
+
+ BLI_snprintf(expression, maxlen, "%s%.3f", dvar_prefix, fval);
+ BLI_str_rstrip_float_zero(expression, '\0');
+ }
+ else if (flag & CREATEDRIVER_WITH_DEFAULT_DVAR) {
+ BLI_strncpy(expression, "var", maxlen);
+ }
+ }
+
+ /* for easier setup of drivers from UI, a driver variable should be
+ * added if flag is set (UI calls only)
+ */
+ if (flag & CREATEDRIVER_WITH_DEFAULT_DVAR) {
+ /* assume that users will mostly want this to be of type "Transform Channel" too,
+ * since this allows the easiest setting up of common rig components
+ */
+ DriverVar *dvar = driver_add_new_variable(driver);
+ driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
+ }
+ }
+
+ /* set the done status */
+ done_tot += (fcu != NULL);
+ }
+
+ /* done */
+ return done_tot;
}
/* Main Driver Management API calls:
* Remove the driver for the specified property on the given ID block (if available)
*/
-bool ANIM_remove_driver(ReportList *UNUSED(reports), ID *id, const char rna_path[], int array_index, short UNUSED(flag))
+bool ANIM_remove_driver(ReportList *UNUSED(reports),
+ ID *id,
+ const char rna_path[],
+ int array_index,
+ short UNUSED(flag))
{
- AnimData *adt;
- FCurve *fcu;
- bool success = false;
-
- /* we don't check the validity of the path here yet, but it should be ok... */
- adt = BKE_animdata_from_id(id);
-
- if (adt) {
- if (array_index == -1) {
- /* step through all drivers, removing all of those with the same base path */
- FCurve *fcu_iter = adt->drivers.first;
-
- while ((fcu = iter_step_fcurve(fcu_iter, rna_path)) != NULL) {
- /* store the next fcurve for looping */
- fcu_iter = fcu->next;
-
- /* remove F-Curve from driver stack, then free it */
- BLI_remlink(&adt->drivers, fcu);
- free_fcurve(fcu);
-
- /* done successfully */
- success = true;
- }
- }
- else {
- /* find the matching driver and remove it only
- * Note: here is one of the places where we don't want new F-Curve + Driver added!
- * so 'add' var must be 0
- */
- fcu = verify_driver_fcurve(id, rna_path, array_index, 0);
- if (fcu) {
- BLI_remlink(&adt->drivers, fcu);
- free_fcurve(fcu);
-
- success = true;
- }
- }
- }
-
- return success;
+ AnimData *adt;
+ FCurve *fcu;
+ bool success = false;
+
+ /* we don't check the validity of the path here yet, but it should be ok... */
+ adt = BKE_animdata_from_id(id);
+
+ if (adt) {
+ if (array_index == -1) {
+ /* step through all drivers, removing all of those with the same base path */
+ FCurve *fcu_iter = adt->drivers.first;
+
+ while ((fcu = iter_step_fcurve(fcu_iter, rna_path)) != NULL) {
+ /* store the next fcurve for looping */
+ fcu_iter = fcu->next;
+
+ /* remove F-Curve from driver stack, then free it */
+ BLI_remlink(&adt->drivers, fcu);
+ free_fcurve(fcu);
+
+ /* done successfully */
+ success = true;
+ }
+ }
+ else {
+ /* find the matching driver and remove it only
+ * Note: here is one of the places where we don't want new F-Curve + Driver added!
+ * so 'add' var must be 0
+ */
+ fcu = verify_driver_fcurve(id, rna_path, array_index, 0);
+ if (fcu) {
+ BLI_remlink(&adt->drivers, fcu);
+ free_fcurve(fcu);
+
+ success = true;
+ }
+ }
+ }
+
+ return success;
}
/* ************************************************** */
@@ -525,16 +585,16 @@ static FCurve *channeldriver_copypaste_buf = NULL;
/* This function frees any MEM_calloc'ed copy/paste buffer data */
void ANIM_drivers_copybuf_free(void)
{
- /* free the buffer F-Curve if it exists, as if it were just another F-Curve */
- if (channeldriver_copypaste_buf)
- free_fcurve(channeldriver_copypaste_buf);
- channeldriver_copypaste_buf = NULL;
+ /* free the buffer F-Curve if it exists, as if it were just another F-Curve */
+ if (channeldriver_copypaste_buf)
+ free_fcurve(channeldriver_copypaste_buf);
+ channeldriver_copypaste_buf = NULL;
}
/* Checks if there is a driver in the copy/paste buffer */
bool ANIM_driver_can_paste(void)
{
- return (channeldriver_copypaste_buf != NULL);
+ return (channeldriver_copypaste_buf != NULL);
}
/* ------------------- */
@@ -542,98 +602,106 @@ bool ANIM_driver_can_paste(void)
/* Main Driver Management API calls:
* Make a copy of the driver for the specified property on the given ID block
*/
-bool ANIM_copy_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
+bool ANIM_copy_driver(
+ ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
{
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
- FCurve *fcu;
-
- /* validate pointer first - exit if failure */
- RNA_id_pointer_create(id, &id_ptr);
- if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
- BKE_reportf(reports, RPT_ERROR,
- "Could not find driver to copy, as RNA path is invalid for the given ID (ID = %s, path = %s)",
- id->name, rna_path);
- return 0;
- }
-
- /* try to get F-Curve with Driver */
- fcu = verify_driver_fcurve(id, rna_path, array_index, 0);
-
- /* clear copy/paste buffer first (for consistency with other copy/paste buffers) */
- ANIM_drivers_copybuf_free();
-
- /* copy this to the copy/paste buf if it exists */
- if (fcu && fcu->driver) {
- /* make copies of some info such as the rna_path, then clear this info from the F-Curve temporarily
- * so that we don't end up wasting memory storing the path which won't get used ever...
- */
- char *tmp_path = fcu->rna_path;
- fcu->rna_path = NULL;
-
- /* make a copy of the F-Curve with */
- channeldriver_copypaste_buf = copy_fcurve(fcu);
-
- /* restore the path */
- fcu->rna_path = tmp_path;
-
- /* copied... */
- return 1;
- }
-
- /* done */
- return 0;
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ FCurve *fcu;
+
+ /* validate pointer first - exit if failure */
+ RNA_id_pointer_create(id, &id_ptr);
+ if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "Could not find driver to copy, as RNA path is invalid for the given ID (ID = %s, "
+ "path = %s)",
+ id->name,
+ rna_path);
+ return 0;
+ }
+
+ /* try to get F-Curve with Driver */
+ fcu = verify_driver_fcurve(id, rna_path, array_index, 0);
+
+ /* clear copy/paste buffer first (for consistency with other copy/paste buffers) */
+ ANIM_drivers_copybuf_free();
+
+ /* copy this to the copy/paste buf if it exists */
+ if (fcu && fcu->driver) {
+ /* make copies of some info such as the rna_path, then clear this info from the F-Curve temporarily
+ * so that we don't end up wasting memory storing the path which won't get used ever...
+ */
+ char *tmp_path = fcu->rna_path;
+ fcu->rna_path = NULL;
+
+ /* make a copy of the F-Curve with */
+ channeldriver_copypaste_buf = copy_fcurve(fcu);
+
+ /* restore the path */
+ fcu->rna_path = tmp_path;
+
+ /* copied... */
+ return 1;
+ }
+
+ /* done */
+ return 0;
}
/* Main Driver Management API calls:
* Add a new driver for the specified property on the given ID block or replace an existing one
* with the driver + driver-curve data from the buffer
*/
-bool ANIM_paste_driver(ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
+bool ANIM_paste_driver(
+ ReportList *reports, ID *id, const char rna_path[], int array_index, short UNUSED(flag))
{
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
- FCurve *fcu;
-
- /* validate pointer first - exit if failure */
- RNA_id_pointer_create(id, &id_ptr);
- if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
- BKE_reportf(reports, RPT_ERROR,
- "Could not paste driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
- id->name, rna_path);
- return 0;
- }
-
- /* if the buffer is empty, cannot paste... */
- if (channeldriver_copypaste_buf == NULL) {
- BKE_report(reports, RPT_ERROR, "Paste driver: no driver to paste");
- return 0;
- }
-
- /* create Driver F-Curve, but without data which will be copied across... */
- fcu = verify_driver_fcurve(id, rna_path, array_index, -1);
-
- if (fcu) {
- /* copy across the curve data from the buffer curve
- * NOTE: this step needs care to not miss new settings
- */
- /* keyframes/samples */
- fcu->bezt = MEM_dupallocN(channeldriver_copypaste_buf->bezt);
- fcu->fpt = MEM_dupallocN(channeldriver_copypaste_buf->fpt);
- fcu->totvert = channeldriver_copypaste_buf->totvert;
-
- /* modifiers */
- copy_fmodifiers(&fcu->modifiers, &channeldriver_copypaste_buf->modifiers);
-
- /* extrapolation mode */
- fcu->extend = channeldriver_copypaste_buf->extend;
-
- /* the 'juicy' stuff - the driver */
- fcu->driver = fcurve_copy_driver(channeldriver_copypaste_buf->driver);
- }
-
- /* done */
- return (fcu != NULL);
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ FCurve *fcu;
+
+ /* validate pointer first - exit if failure */
+ RNA_id_pointer_create(id, &id_ptr);
+ if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
+ BKE_reportf(
+ reports,
+ RPT_ERROR,
+ "Could not paste driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
+ id->name,
+ rna_path);
+ return 0;
+ }
+
+ /* if the buffer is empty, cannot paste... */
+ if (channeldriver_copypaste_buf == NULL) {
+ BKE_report(reports, RPT_ERROR, "Paste driver: no driver to paste");
+ return 0;
+ }
+
+ /* create Driver F-Curve, but without data which will be copied across... */
+ fcu = verify_driver_fcurve(id, rna_path, array_index, -1);
+
+ if (fcu) {
+ /* copy across the curve data from the buffer curve
+ * NOTE: this step needs care to not miss new settings
+ */
+ /* keyframes/samples */
+ fcu->bezt = MEM_dupallocN(channeldriver_copypaste_buf->bezt);
+ fcu->fpt = MEM_dupallocN(channeldriver_copypaste_buf->fpt);
+ fcu->totvert = channeldriver_copypaste_buf->totvert;
+
+ /* modifiers */
+ copy_fmodifiers(&fcu->modifiers, &channeldriver_copypaste_buf->modifiers);
+
+ /* extrapolation mode */
+ fcu->extend = channeldriver_copypaste_buf->extend;
+
+ /* the 'juicy' stuff - the driver */
+ fcu->driver = fcurve_copy_driver(channeldriver_copypaste_buf->driver);
+ }
+
+ /* done */
+ return (fcu != NULL);
}
/* ************************************************** */
@@ -645,24 +713,24 @@ static ListBase driver_vars_copybuf = {NULL, NULL};
/* This function frees any MEM_calloc'ed copy/paste buffer data */
void ANIM_driver_vars_copybuf_free(void)
{
- /* Free the driver variables kept in the buffer */
- if (driver_vars_copybuf.first) {
- DriverVar *dvar, *dvarn;
-
- /* Free variables (and any data they use) */
- for (dvar = driver_vars_copybuf.first; dvar; dvar = dvarn) {
- dvarn = dvar->next;
- driver_free_variable(&driver_vars_copybuf, dvar);
- }
- }
-
- BLI_listbase_clear(&driver_vars_copybuf);
+ /* Free the driver variables kept in the buffer */
+ if (driver_vars_copybuf.first) {
+ DriverVar *dvar, *dvarn;
+
+ /* Free variables (and any data they use) */
+ for (dvar = driver_vars_copybuf.first; dvar; dvar = dvarn) {
+ dvarn = dvar->next;
+ driver_free_variable(&driver_vars_copybuf, dvar);
+ }
+ }
+
+ BLI_listbase_clear(&driver_vars_copybuf);
}
/* Checks if there are driver variables in the copy/paste buffer */
bool ANIM_driver_vars_can_paste(void)
{
- return (BLI_listbase_is_empty(&driver_vars_copybuf) == false);
+ return (BLI_listbase_is_empty(&driver_vars_copybuf) == false);
}
/* -------------------------------------------------- */
@@ -670,78 +738,78 @@ bool ANIM_driver_vars_can_paste(void)
/* Copy the given driver's variables to the buffer */
bool ANIM_driver_vars_copy(ReportList *reports, FCurve *fcu)
{
- /* sanity checks */
- if (ELEM(NULL, fcu, fcu->driver)) {
- BKE_report(reports, RPT_ERROR, "No driver to copy variables from");
- return false;
- }
+ /* sanity checks */
+ if (ELEM(NULL, fcu, fcu->driver)) {
+ BKE_report(reports, RPT_ERROR, "No driver to copy variables from");
+ return false;
+ }
- if (BLI_listbase_is_empty(&fcu->driver->variables)) {
- BKE_report(reports, RPT_ERROR, "Driver has no variables to copy");
- return false;
- }
+ if (BLI_listbase_is_empty(&fcu->driver->variables)) {
+ BKE_report(reports, RPT_ERROR, "Driver has no variables to copy");
+ return false;
+ }
- /* clear buffer */
- ANIM_driver_vars_copybuf_free();
+ /* clear buffer */
+ ANIM_driver_vars_copybuf_free();
- /* copy over the variables */
- driver_variables_copy(&driver_vars_copybuf, &fcu->driver->variables);
+ /* copy over the variables */
+ driver_variables_copy(&driver_vars_copybuf, &fcu->driver->variables);
- return (BLI_listbase_is_empty(&driver_vars_copybuf) == false);
+ return (BLI_listbase_is_empty(&driver_vars_copybuf) == false);
}
/* Paste the variables in the buffer to the given FCurve */
bool ANIM_driver_vars_paste(ReportList *reports, FCurve *fcu, bool replace)
{
- ChannelDriver *driver = (fcu) ? fcu->driver : NULL;
- ListBase tmp_list = {NULL, NULL};
-
- /* sanity checks */
- if (BLI_listbase_is_empty(&driver_vars_copybuf)) {
- BKE_report(reports, RPT_ERROR, "No driver variables in clipboard to paste");
- return false;
- }
-
- if (ELEM(NULL, fcu, fcu->driver)) {
- BKE_report(reports, RPT_ERROR, "Cannot paste driver variables without a driver");
- return false;
- }
-
- /* 1) Make a new copy of the variables in the buffer - these will get pasted later... */
- driver_variables_copy(&tmp_list, &driver_vars_copybuf);
-
- /* 2) Prepare destination array */
- if (replace) {
- DriverVar *dvar, *dvarn;
-
- /* Free all existing vars first - We aren't retaining anything */
- for (dvar = driver->variables.first; dvar; dvar = dvarn) {
- dvarn = dvar->next;
- driver_free_variable_ex(driver, dvar);
- }
-
- BLI_listbase_clear(&driver->variables);
- }
-
- /* 3) Add new vars */
- if (driver->variables.last) {
- DriverVar *last = driver->variables.last;
- DriverVar *first = tmp_list.first;
-
- last->next = first;
- first->prev = last;
-
- driver->variables.last = tmp_list.last;
- }
- else {
- driver->variables.first = tmp_list.first;
- driver->variables.last = tmp_list.last;
- }
-
- /* since driver variables are cached, the expression needs re-compiling too */
- BKE_driver_invalidate_expression(driver, false, true);
-
- return true;
+ ChannelDriver *driver = (fcu) ? fcu->driver : NULL;
+ ListBase tmp_list = {NULL, NULL};
+
+ /* sanity checks */
+ if (BLI_listbase_is_empty(&driver_vars_copybuf)) {
+ BKE_report(reports, RPT_ERROR, "No driver variables in clipboard to paste");
+ return false;
+ }
+
+ if (ELEM(NULL, fcu, fcu->driver)) {
+ BKE_report(reports, RPT_ERROR, "Cannot paste driver variables without a driver");
+ return false;
+ }
+
+ /* 1) Make a new copy of the variables in the buffer - these will get pasted later... */
+ driver_variables_copy(&tmp_list, &driver_vars_copybuf);
+
+ /* 2) Prepare destination array */
+ if (replace) {
+ DriverVar *dvar, *dvarn;
+
+ /* Free all existing vars first - We aren't retaining anything */
+ for (dvar = driver->variables.first; dvar; dvar = dvarn) {
+ dvarn = dvar->next;
+ driver_free_variable_ex(driver, dvar);
+ }
+
+ BLI_listbase_clear(&driver->variables);
+ }
+
+ /* 3) Add new vars */
+ if (driver->variables.last) {
+ DriverVar *last = driver->variables.last;
+ DriverVar *first = tmp_list.first;
+
+ last->next = first;
+ first->prev = last;
+
+ driver->variables.last = tmp_list.last;
+ }
+ else {
+ driver->variables.first = tmp_list.first;
+ driver->variables.last = tmp_list.last;
+ }
+
+ /* since driver variables are cached, the expression needs re-compiling too */
+ BKE_driver_invalidate_expression(driver, false, true);
+
+ return true;
}
/* ************************************************** */
@@ -753,397 +821,421 @@ bool ANIM_driver_vars_paste(ReportList *reports, FCurve *fcu, bool replace)
/* NOTE: Used by ANIM_OT_driver_button_add and UI_OT_eyedropper_driver */
// XXX: These names need reviewing
EnumPropertyItem prop_driver_create_mapping_types[] = {
- {CREATEDRIVER_MAPPING_1_N, "SINGLE_MANY", 0, "All from Target",
- "Drive all components of this property using the target picked"},
- {CREATEDRIVER_MAPPING_1_1, "DIRECT", 0, "Single from Target",
- "Drive this component of this property using the target picked"},
-
- {CREATEDRIVER_MAPPING_N_N, "MATCH", ICON_COLOR, "Match Indices",
- "Create drivers for each pair of corresponding elements"},
-
- {CREATEDRIVER_MAPPING_NONE_ALL, "NONE_ALL", ICON_HAND, "Manually Create Later",
- "Create drivers for all properties without assigning any targets yet"},
- {CREATEDRIVER_MAPPING_NONE, "NONE_SINGLE", 0, "Manually Create Later (Single)",
- "Create driver for this property only and without assigning any targets yet"},
- {0, NULL, 0, NULL, NULL},
+ {CREATEDRIVER_MAPPING_1_N,
+ "SINGLE_MANY",
+ 0,
+ "All from Target",
+ "Drive all components of this property using the target picked"},
+ {CREATEDRIVER_MAPPING_1_1,
+ "DIRECT",
+ 0,
+ "Single from Target",
+ "Drive this component of this property using the target picked"},
+
+ {CREATEDRIVER_MAPPING_N_N,
+ "MATCH",
+ ICON_COLOR,
+ "Match Indices",
+ "Create drivers for each pair of corresponding elements"},
+
+ {CREATEDRIVER_MAPPING_NONE_ALL,
+ "NONE_ALL",
+ ICON_HAND,
+ "Manually Create Later",
+ "Create drivers for all properties without assigning any targets yet"},
+ {CREATEDRIVER_MAPPING_NONE,
+ "NONE_SINGLE",
+ 0,
+ "Manually Create Later (Single)",
+ "Create driver for this property only and without assigning any targets yet"},
+ {0, NULL, 0, NULL, NULL},
};
/* Filtering callback for driver mapping types enum */
-static const EnumPropertyItem *driver_mapping_type_itemsf(bContext *C, PointerRNA *UNUSED(owner_ptr), PropertyRNA *UNUSED(owner_prop), bool *r_free)
+static const EnumPropertyItem *driver_mapping_type_itemsf(bContext *C,
+ PointerRNA *UNUSED(owner_ptr),
+ PropertyRNA *UNUSED(owner_prop),
+ bool *r_free)
{
- EnumPropertyItem *input = prop_driver_create_mapping_types;
- EnumPropertyItem *item = NULL;
+ EnumPropertyItem *input = prop_driver_create_mapping_types;
+ EnumPropertyItem *item = NULL;
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
- int index;
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ int index;
- int totitem = 0;
+ int totitem = 0;
- if (!C) /* needed for docs */
- return prop_driver_create_mapping_types;
+ if (!C) /* needed for docs */
+ return prop_driver_create_mapping_types;
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
- const bool is_array = RNA_property_array_check(prop);
+ if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
+ const bool is_array = RNA_property_array_check(prop);
- while (input->identifier) {
- if (ELEM(input->value, CREATEDRIVER_MAPPING_1_1, CREATEDRIVER_MAPPING_NONE) || (is_array)) {
- RNA_enum_item_add(&item, &totitem, input);
- }
- input++;
- }
- }
- else {
- /* We need at least this one! */
- RNA_enum_items_add_value(&item, &totitem, input, CREATEDRIVER_MAPPING_NONE);
- }
+ while (input->identifier) {
+ if (ELEM(input->value, CREATEDRIVER_MAPPING_1_1, CREATEDRIVER_MAPPING_NONE) || (is_array)) {
+ RNA_enum_item_add(&item, &totitem, input);
+ }
+ input++;
+ }
+ }
+ else {
+ /* We need at least this one! */
+ RNA_enum_items_add_value(&item, &totitem, input, CREATEDRIVER_MAPPING_NONE);
+ }
- RNA_enum_item_end(&item, &totitem);
+ RNA_enum_item_end(&item, &totitem);
- *r_free = true;
- return item;
+ *r_free = true;
+ return item;
}
-
/* Add Driver (With Menu) Button Operator ------------------------ */
static bool add_driver_button_poll(bContext *C)
{
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
- int index;
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ int index;
- /* this operator can only run if there's a property button active, and it can be animated */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- return (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop));
+ /* this operator can only run if there's a property button active, and it can be animated */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ return (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop));
}
/* Wrapper for creating a driver without knowing what the targets will be yet (i.e. "manual/add later") */
static int add_driver_button_none(bContext *C, wmOperator *op, short mapping_type)
{
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
- int index;
- int success = 0;
-
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
- if (mapping_type == CREATEDRIVER_MAPPING_NONE_ALL)
- index = -1;
-
- if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
- char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
- short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
-
- if (path) {
- success += ANIM_add_driver(op->reports, ptr.id.data, path, index, flags, DRIVER_TYPE_PYTHON);
- MEM_freeN(path);
- }
- }
-
- if (success) {
- /* send updates */
- UI_context_update_anim_flag(C);
- DEG_relations_tag_update(CTX_data_main(C));
- WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
-
- return OPERATOR_FINISHED;
- }
- else {
- return OPERATOR_CANCELLED;
- }
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ int index;
+ int success = 0;
+
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+
+ if (mapping_type == CREATEDRIVER_MAPPING_NONE_ALL)
+ index = -1;
+
+ if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
+ char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
+ short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
+
+ if (path) {
+ success += ANIM_add_driver(op->reports, ptr.id.data, path, index, flags, DRIVER_TYPE_PYTHON);
+ MEM_freeN(path);
+ }
+ }
+
+ if (success) {
+ /* send updates */
+ UI_context_update_anim_flag(C);
+ DEG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
}
static int add_driver_button_menu_exec(bContext *C, wmOperator *op)
{
- short mapping_type = RNA_enum_get(op->ptr, "mapping_type");
- if (ELEM(mapping_type, CREATEDRIVER_MAPPING_NONE, CREATEDRIVER_MAPPING_NONE_ALL)) {
- /* Just create driver with no targets */
- return add_driver_button_none(C, op, mapping_type);
- }
- else {
- /* Create Driver using Eyedropper */
- wmOperatorType *ot = WM_operatortype_find("UI_OT_eyedropper_driver", true);
-
- /* XXX: We assume that it's fine to use the same set of properties, since they're actually the same... */
- WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, op->ptr);
-
- return OPERATOR_FINISHED;
- }
+ short mapping_type = RNA_enum_get(op->ptr, "mapping_type");
+ if (ELEM(mapping_type, CREATEDRIVER_MAPPING_NONE, CREATEDRIVER_MAPPING_NONE_ALL)) {
+ /* Just create driver with no targets */
+ return add_driver_button_none(C, op, mapping_type);
+ }
+ else {
+ /* Create Driver using Eyedropper */
+ wmOperatorType *ot = WM_operatortype_find("UI_OT_eyedropper_driver", true);
+
+ /* XXX: We assume that it's fine to use the same set of properties, since they're actually the same... */
+ WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, op->ptr);
+
+ return OPERATOR_FINISHED;
+ }
}
/* Show menu or create drivers */
static int add_driver_button_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- PropertyRNA *prop;
-
- if ((prop = RNA_struct_find_property(op->ptr, "mapping_type")) && RNA_property_is_set(op->ptr, prop)) {
- /* Mapping Type is Set - Directly go into creating drivers */
- return add_driver_button_menu_exec(C, op);
- }
- else {
- /* Show menu */
- // TODO: This should get filtered by the enum filter
- /* important to execute in the region we're currently in */
- return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_DEFAULT);
- }
+ PropertyRNA *prop;
+
+ if ((prop = RNA_struct_find_property(op->ptr, "mapping_type")) &&
+ RNA_property_is_set(op->ptr, prop)) {
+ /* Mapping Type is Set - Directly go into creating drivers */
+ return add_driver_button_menu_exec(C, op);
+ }
+ else {
+ /* Show menu */
+ // TODO: This should get filtered by the enum filter
+ /* important to execute in the region we're currently in */
+ return WM_menu_invoke_ex(C, op, WM_OP_INVOKE_DEFAULT);
+ }
}
static void UNUSED_FUNCTION(ANIM_OT_driver_button_add_menu)(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Driver Menu";
- ot->idname = "ANIM_OT_driver_button_add_menu";
- ot->description = "Add driver(s) for the property(s) represented by the highlighted button";
-
- /* callbacks */
- ot->invoke = add_driver_button_menu_invoke;
- ot->exec = add_driver_button_menu_exec;
- ot->poll = add_driver_button_poll;
-
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
-
- /* properties */
- ot->prop = RNA_def_enum(ot->srna, "mapping_type", prop_driver_create_mapping_types, 0,
- "Mapping Type", "Method used to match target and driven properties");
- RNA_def_enum_funcs(ot->prop, driver_mapping_type_itemsf);
+ /* identifiers */
+ ot->name = "Add Driver Menu";
+ ot->idname = "ANIM_OT_driver_button_add_menu";
+ ot->description = "Add driver(s) for the property(s) represented by the highlighted button";
+
+ /* callbacks */
+ ot->invoke = add_driver_button_menu_invoke;
+ ot->exec = add_driver_button_menu_exec;
+ ot->poll = add_driver_button_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+
+ /* properties */
+ ot->prop = RNA_def_enum(ot->srna,
+ "mapping_type",
+ prop_driver_create_mapping_types,
+ 0,
+ "Mapping Type",
+ "Method used to match target and driven properties");
+ RNA_def_enum_funcs(ot->prop, driver_mapping_type_itemsf);
}
/* Add Driver Button Operator ------------------------ */
static int add_driver_button_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
- int index;
-
- /* try to find driver using property retrieved from UI */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
-
- if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
- /* 1) Create a new "empty" driver for this property */
- char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
- short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
- short success = 0;
-
- if (path) {
- success += ANIM_add_driver(op->reports, ptr.id.data, path, index, flags, DRIVER_TYPE_PYTHON);
- MEM_freeN(path);
- }
-
- if (success) {
- /* send updates */
- UI_context_update_anim_flag(C);
- DEG_id_tag_update(ptr.id.data, ID_RECALC_COPY_ON_WRITE);
- DEG_relations_tag_update(CTX_data_main(C));
- WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL);
- }
-
- /* 2) Show editing panel for setting up this driver */
- /* TODO: Use a different one from the editing popever, so we can have the single/all toggle? */
- UI_popover_panel_invoke(C, "GRAPH_PT_drivers_popover", true, op->reports);
- }
-
- return OPERATOR_INTERFACE;
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ int index;
+
+ /* try to find driver using property retrieved from UI */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+
+ if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
+ /* 1) Create a new "empty" driver for this property */
+ char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
+ short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
+ short success = 0;
+
+ if (path) {
+ success += ANIM_add_driver(op->reports, ptr.id.data, path, index, flags, DRIVER_TYPE_PYTHON);
+ MEM_freeN(path);
+ }
+
+ if (success) {
+ /* send updates */
+ UI_context_update_anim_flag(C);
+ DEG_id_tag_update(ptr.id.data, ID_RECALC_COPY_ON_WRITE);
+ DEG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL);
+ }
+
+ /* 2) Show editing panel for setting up this driver */
+ /* TODO: Use a different one from the editing popever, so we can have the single/all toggle? */
+ UI_popover_panel_invoke(C, "GRAPH_PT_drivers_popover", true, op->reports);
+ }
+
+ return OPERATOR_INTERFACE;
}
void ANIM_OT_driver_button_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Driver";
- ot->idname = "ANIM_OT_driver_button_add";
- ot->description = "Add driver for the property under the cursor";
-
- /* callbacks */
- /* NOTE: No exec, as we need all these to use the current context info */
- ot->invoke = add_driver_button_invoke;
- ot->poll = add_driver_button_poll;
-
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* identifiers */
+ ot->name = "Add Driver";
+ ot->idname = "ANIM_OT_driver_button_add";
+ ot->description = "Add driver for the property under the cursor";
+
+ /* callbacks */
+ /* NOTE: No exec, as we need all these to use the current context info */
+ ot->invoke = add_driver_button_invoke;
+ ot->poll = add_driver_button_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/* Remove Driver Button Operator ------------------------ */
static int remove_driver_button_exec(bContext *C, wmOperator *op)
{
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
- short success = 0;
- int index;
- const bool all = RNA_boolean_get(op->ptr, "all");
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ short success = 0;
+ int index;
+ const bool all = RNA_boolean_get(op->ptr, "all");
- /* try to find driver using property retrieved from UI */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ /* try to find driver using property retrieved from UI */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- if (all)
- index = -1;
+ if (all)
+ index = -1;
- if (ptr.id.data && ptr.data && prop) {
- char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
+ if (ptr.id.data && ptr.data && prop) {
+ char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
- if (path) {
- success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);
+ if (path) {
+ success = ANIM_remove_driver(op->reports, ptr.id.data, path, index, 0);
- MEM_freeN(path);
- }
- }
+ MEM_freeN(path);
+ }
+ }
- if (success) {
- /* send updates */
- UI_context_update_anim_flag(C);
- DEG_relations_tag_update(CTX_data_main(C));
- WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
- }
+ if (success) {
+ /* send updates */
+ UI_context_update_anim_flag(C);
+ DEG_relations_tag_update(CTX_data_main(C));
+ WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
+ }
- return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void ANIM_OT_driver_button_remove(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Driver";
- ot->idname = "ANIM_OT_driver_button_remove";
- ot->description = "Remove the driver(s) for the property(s) connected represented by the highlighted button";
+ /* identifiers */
+ ot->name = "Remove Driver";
+ ot->idname = "ANIM_OT_driver_button_remove";
+ ot->description =
+ "Remove the driver(s) for the property(s) connected represented by the highlighted button";
- /* callbacks */
- ot->exec = remove_driver_button_exec;
- //op->poll = ??? // TODO: need to have some driver to be able to do this...
+ /* callbacks */
+ ot->exec = remove_driver_button_exec;
+ //op->poll = ??? // TODO: need to have some driver to be able to do this...
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
- /* properties */
- RNA_def_boolean(ot->srna, "all", 1, "All", "Delete drivers for all elements of the array");
+ /* properties */
+ RNA_def_boolean(ot->srna, "all", 1, "All", "Delete drivers for all elements of the array");
}
/* Edit Driver Button Operator ------------------------ */
static int edit_driver_button_exec(bContext *C, wmOperator *op)
{
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
- int index;
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ int index;
- /* try to find driver using property retrieved from UI */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ /* try to find driver using property retrieved from UI */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- if (ptr.id.data && ptr.data && prop) {
- UI_popover_panel_invoke(C, "GRAPH_PT_drivers_popover", true, op->reports);
- }
+ if (ptr.id.data && ptr.data && prop) {
+ UI_popover_panel_invoke(C, "GRAPH_PT_drivers_popover", true, op->reports);
+ }
- return OPERATOR_INTERFACE;
+ return OPERATOR_INTERFACE;
}
void ANIM_OT_driver_button_edit(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Edit Driver";
- ot->idname = "ANIM_OT_driver_button_edit";
- ot->description = "Edit the drivers for the property connected represented by the highlighted button";
-
- /* callbacks */
- ot->exec = edit_driver_button_exec;
- //op->poll = ??? // TODO: need to have some driver to be able to do this...
-
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* identifiers */
+ ot->name = "Edit Driver";
+ ot->idname = "ANIM_OT_driver_button_edit";
+ ot->description =
+ "Edit the drivers for the property connected represented by the highlighted button";
+
+ /* callbacks */
+ ot->exec = edit_driver_button_exec;
+ //op->poll = ??? // TODO: need to have some driver to be able to do this...
+
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/* Copy Driver Button Operator ------------------------ */
static int copy_driver_button_exec(bContext *C, wmOperator *op)
{
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
- short success = 0;
- int index;
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ short success = 0;
+ int index;
- /* try to create driver using property retrieved from UI */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ /* try to create driver using property retrieved from UI */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
- char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
+ if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
+ char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
- if (path) {
- /* only copy the driver for the button that this was involved for */
- success = ANIM_copy_driver(op->reports, ptr.id.data, path, index, 0);
+ if (path) {
+ /* only copy the driver for the button that this was involved for */
+ success = ANIM_copy_driver(op->reports, ptr.id.data, path, index, 0);
- UI_context_update_anim_flag(C);
+ UI_context_update_anim_flag(C);
- MEM_freeN(path);
- }
- }
+ MEM_freeN(path);
+ }
+ }
- /* since we're just copying, we don't really need to do anything else...*/
- return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ /* since we're just copying, we don't really need to do anything else...*/
+ return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void ANIM_OT_copy_driver_button(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Copy Driver";
- ot->idname = "ANIM_OT_copy_driver_button";
- ot->description = "Copy the driver for the highlighted button";
+ /* identifiers */
+ ot->name = "Copy Driver";
+ ot->idname = "ANIM_OT_copy_driver_button";
+ ot->description = "Copy the driver for the highlighted button";
- /* callbacks */
- ot->exec = copy_driver_button_exec;
- //op->poll = ??? // TODO: need to have some driver to be able to do this...
+ /* callbacks */
+ ot->exec = copy_driver_button_exec;
+ //op->poll = ??? // TODO: need to have some driver to be able to do this...
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/* Paste Driver Button Operator ------------------------ */
static int paste_driver_button_exec(bContext *C, wmOperator *op)
{
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
- short success = 0;
- int index;
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ short success = 0;
+ int index;
- /* try to create driver using property retrieved from UI */
- UI_context_active_but_prop_get(C, &ptr, &prop, &index);
+ /* try to create driver using property retrieved from UI */
+ UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
- char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
+ if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
+ char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
- if (path) {
- /* only copy the driver for the button that this was involved for */
- success = ANIM_paste_driver(op->reports, ptr.id.data, path, index, 0);
+ if (path) {
+ /* only copy the driver for the button that this was involved for */
+ success = ANIM_paste_driver(op->reports, ptr.id.data, path, index, 0);
- UI_context_update_anim_flag(C);
+ UI_context_update_anim_flag(C);
- DEG_relations_tag_update(CTX_data_main(C));
- DEG_id_tag_update(ptr.id.data, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ DEG_relations_tag_update(CTX_data_main(C));
+ DEG_id_tag_update(ptr.id.data, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL); // XXX
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME_PROP, NULL); // XXX
- MEM_freeN(path);
- }
- }
+ MEM_freeN(path);
+ }
+ }
- /* since we're just copying, we don't really need to do anything else...*/
- return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ /* since we're just copying, we don't really need to do anything else...*/
+ return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void ANIM_OT_paste_driver_button(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Paste Driver";
- ot->idname = "ANIM_OT_paste_driver_button";
- ot->description = "Paste the driver in the copy/paste buffer for the highlighted button";
+ /* identifiers */
+ ot->name = "Paste Driver";
+ ot->idname = "ANIM_OT_paste_driver_button";
+ ot->description = "Paste the driver in the copy/paste buffer for the highlighted button";
- /* callbacks */
- ot->exec = paste_driver_button_exec;
- //op->poll = ??? // TODO: need to have some driver to be able to do this...
+ /* callbacks */
+ ot->exec = paste_driver_button_exec;
+ //op->poll = ??? // TODO: need to have some driver to be able to do this...
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
}
/* ************************************************** */
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index 8edad506a33..919090cdee9 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
/* User-Interface Stuff for F-Modifiers:
* This file defines the (C-Coded) templates + editing callbacks needed
* by the interface stuff or F-Modifiers, as used by F-Curves in the Graph Editor,
@@ -65,635 +64,939 @@
// XXX! --------------------------------
/* temporary definition for limits of float number buttons (FLT_MAX tends to infinity with old system) */
-#define UI_FLT_MAX 10000.0f
+#define UI_FLT_MAX 10000.0f
-#define B_REDR 1
-#define B_FMODIFIER_REDRAW 20
+#define B_REDR 1
+#define B_FMODIFIER_REDRAW 20
/* callback to verify modifier data */
static void validate_fmodifier_cb(bContext *UNUSED(C), void *fcm_v, void *UNUSED(arg))
{
- FModifier *fcm = (FModifier *)fcm_v;
- const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
+ FModifier *fcm = (FModifier *)fcm_v;
+ const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
- /* call the verify callback on the modifier if applicable */
- if (fmi && fmi->verify_data)
- fmi->verify_data(fcm);
+ /* call the verify callback on the modifier if applicable */
+ if (fmi && fmi->verify_data)
+ fmi->verify_data(fcm);
}
/* callback to remove the given modifier */
typedef struct FModifierDeleteContext {
- ID *fcurve_owner_id;
- ListBase *modifiers;
+ ID *fcurve_owner_id;
+ ListBase *modifiers;
} FModifierDeleteContext;
static void delete_fmodifier_cb(bContext *C, void *ctx_v, void *fcm_v)
{
- FModifierDeleteContext *ctx = (FModifierDeleteContext *)ctx_v;
- ListBase *modifiers = ctx->modifiers;
- FModifier *fcm = (FModifier *)fcm_v;
+ FModifierDeleteContext *ctx = (FModifierDeleteContext *)ctx_v;
+ ListBase *modifiers = ctx->modifiers;
+ FModifier *fcm = (FModifier *)fcm_v;
- /* remove the given F-Modifier from the active modifier-stack */
- remove_fmodifier(modifiers, fcm);
+ /* remove the given F-Modifier from the active modifier-stack */
+ remove_fmodifier(modifiers, fcm);
- ED_undo_push(C, "Delete F-Curve Modifier");
+ ED_undo_push(C, "Delete F-Curve Modifier");
- /* send notifiers */
- // XXX for now, this is the only way to get updates in all the right places... but would be nice to have a special one in this case
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- DEG_id_tag_update(ctx->fcurve_owner_id, ID_RECALC_ANIMATION);
+ /* send notifiers */
+ // XXX for now, this is the only way to get updates in all the right places... but would be nice to have a special one in this case
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ DEG_id_tag_update(ctx->fcurve_owner_id, ID_RECALC_ANIMATION);
}
/* --------------- */
/* draw settings for generator modifier */
-static void draw_modifier__generator(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short width)
+static void draw_modifier__generator(uiLayout *layout,
+ ID *fcurve_owner_id,
+ FModifier *fcm,
+ short width)
{
- FMod_Generator *data = (FMod_Generator *)fcm->data;
- uiLayout /* *col, */ /* UNUSED */ *row;
- uiBlock *block;
- uiBut *but;
- PointerRNA ptr;
- short bwidth = width - 1.5 * UI_UNIT_X; /* max button width */
-
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
-
- /* basic settings (backdrop + mode selector + some padding) */
- /* col = uiLayoutColumn(layout, true); */ /* UNUSED */
- block = uiLayoutGetBlock(layout);
- UI_block_align_begin(block);
- but = uiDefButR(block, UI_BTYPE_MENU, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "mode", -1, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
-
- uiDefButR(block, UI_BTYPE_TOGGLE, B_FMODIFIER_REDRAW, NULL, 0, 0, bwidth, UI_UNIT_Y, &ptr, "use_additive", -1, 0, 0, -1, -1, NULL);
- UI_block_align_end(block);
-
- /* now add settings for individual modes */
- switch (data->mode) {
- case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
- {
- const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- float *cp = NULL;
- char xval[32];
- unsigned int i;
- int maxXWidth;
-
- /* draw polynomial order selector */
- row = uiLayoutRow(layout, false);
- block = uiLayoutGetBlock(row);
- but = uiDefButI(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0.5f * UI_UNIT_X, 0, bwidth, UI_UNIT_Y,
- &data->poly_order, 1, 100, 0, 0,
- TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
- UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
-
-
- /* calculate maximum width of label for "x^n" labels */
- if (data->arraysize > 2) {
- BLI_snprintf(xval, sizeof(xval), "x^%u", data->arraysize);
- /* XXX: UI_fontstyle_string_width is not accurate */
- maxXWidth = UI_fontstyle_string_width(fstyle, xval) + 0.5 * UI_UNIT_X;
- }
- else {
- /* basic size (just "x") */
- maxXWidth = UI_fontstyle_string_width(fstyle, "x") + 0.5 * UI_UNIT_X;
- }
-
- /* draw controls for each coefficient and a + sign at end of row */
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
-
- cp = data->coefficients;
- for (i = 0; (i < data->arraysize) && (cp); i++, cp++) {
- /* To align with first line... */
- if (i)
- uiDefBut(block, UI_BTYPE_LABEL, 1, " ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- else
- uiDefBut(block, UI_BTYPE_LABEL, 1, "y =", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
- /* coefficient */
- uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, bwidth / 2, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX,
- 10, 3, TIP_("Coefficient for polynomial"));
-
- /* 'x' param (and '+' if necessary) */
- if (i == 0)
- BLI_strncpy(xval, "", sizeof(xval));
- else if (i == 1)
- BLI_strncpy(xval, "x", sizeof(xval));
- else
- BLI_snprintf(xval, sizeof(xval), "x^%u", i);
- uiDefBut(block, UI_BTYPE_LABEL, 1, xval, 0, 0, maxXWidth, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Power of x"));
-
- if ( (i != (data->arraysize - 1)) || ((i == 0) && data->arraysize == 2) ) {
- uiDefBut(block, UI_BTYPE_LABEL, 1, "+", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
- /* next coefficient on a new row */
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
- }
- else {
- /* For alignment in UI! */
- uiDefBut(block, UI_BTYPE_LABEL, 1, " ", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- }
- }
- break;
- }
-
- case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial expression */
- {
- float *cp = NULL;
- unsigned int i;
-
- /* draw polynomial order selector */
- row = uiLayoutRow(layout, false);
- block = uiLayoutGetBlock(row);
- but = uiDefButI(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Poly Order:"), 0, 0, width - 1.5 * UI_UNIT_X, UI_UNIT_Y,
- &data->poly_order, 1, 100, 0, 0,
- TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
- UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
-
-
- /* draw controls for each pair of coefficients */
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
-
- cp = data->coefficients;
- for (i = 0; (i < data->poly_order) && (cp); i++, cp += 2) {
- /* To align with first line */
- if (i)
- uiDefBut(block, UI_BTYPE_LABEL, 1, " ", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- else
- uiDefBut(block, UI_BTYPE_LABEL, 1, "y =", 0, 0, 2.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- /* opening bracket */
- uiDefBut(block, UI_BTYPE_LABEL, 1, "(", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
- /* coefficients */
- uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp, -UI_FLT_MAX, UI_FLT_MAX,
- 10, 3, TIP_("Coefficient of x"));
-
- uiDefBut(block, UI_BTYPE_LABEL, 1, "x +", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, "", 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y, cp + 1, -UI_FLT_MAX, UI_FLT_MAX,
- 10, 3, TIP_("Second coefficient"));
-
- /* closing bracket and multiplication sign */
- if ( (i != (data->poly_order - 1)) || ((i == 0) && data->poly_order == 2) ) {
- uiDefBut(block, UI_BTYPE_LABEL, 1, ") \xc3\x97", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
- /* set up new row for the next pair of coefficients */
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
- }
- else
- uiDefBut(block, UI_BTYPE_LABEL, 1, ") ", 0, 0, 2 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- }
- break;
- }
- }
+ FMod_Generator *data = (FMod_Generator *)fcm->data;
+ uiLayout /* *col, */ /* UNUSED */ *row;
+ uiBlock *block;
+ uiBut *but;
+ PointerRNA ptr;
+ short bwidth = width - 1.5 * UI_UNIT_X; /* max button width */
+
+ /* init the RNA-pointer */
+ RNA_pointer_create(fcurve_owner_id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
+
+ /* basic settings (backdrop + mode selector + some padding) */
+ /* col = uiLayoutColumn(layout, true); */ /* UNUSED */
+ block = uiLayoutGetBlock(layout);
+ UI_block_align_begin(block);
+ but = uiDefButR(block,
+ UI_BTYPE_MENU,
+ B_FMODIFIER_REDRAW,
+ NULL,
+ 0,
+ 0,
+ bwidth,
+ UI_UNIT_Y,
+ &ptr,
+ "mode",
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
+
+ uiDefButR(block,
+ UI_BTYPE_TOGGLE,
+ B_FMODIFIER_REDRAW,
+ NULL,
+ 0,
+ 0,
+ bwidth,
+ UI_UNIT_Y,
+ &ptr,
+ "use_additive",
+ -1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_block_align_end(block);
+
+ /* now add settings for individual modes */
+ switch (data->mode) {
+ case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
+ {
+ const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
+ float *cp = NULL;
+ char xval[32];
+ unsigned int i;
+ int maxXWidth;
+
+ /* draw polynomial order selector */
+ row = uiLayoutRow(layout, false);
+ block = uiLayoutGetBlock(row);
+ but = uiDefButI(
+ block,
+ UI_BTYPE_NUM,
+ B_FMODIFIER_REDRAW,
+ IFACE_("Poly Order:"),
+ 0.5f * UI_UNIT_X,
+ 0,
+ bwidth,
+ UI_UNIT_Y,
+ &data->poly_order,
+ 1,
+ 100,
+ 0,
+ 0,
+ TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
+ UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
+
+ /* calculate maximum width of label for "x^n" labels */
+ if (data->arraysize > 2) {
+ BLI_snprintf(xval, sizeof(xval), "x^%u", data->arraysize);
+ /* XXX: UI_fontstyle_string_width is not accurate */
+ maxXWidth = UI_fontstyle_string_width(fstyle, xval) + 0.5 * UI_UNIT_X;
+ }
+ else {
+ /* basic size (just "x") */
+ maxXWidth = UI_fontstyle_string_width(fstyle, "x") + 0.5 * UI_UNIT_X;
+ }
+
+ /* draw controls for each coefficient and a + sign at end of row */
+ row = uiLayoutRow(layout, true);
+ block = uiLayoutGetBlock(row);
+
+ cp = data->coefficients;
+ for (i = 0; (i < data->arraysize) && (cp); i++, cp++) {
+ /* To align with first line... */
+ if (i)
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 1,
+ " ",
+ 0,
+ 0,
+ 2 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ else
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 1,
+ "y =",
+ 0,
+ 0,
+ 2 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+
+ /* coefficient */
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_FMODIFIER_REDRAW,
+ "",
+ 0,
+ 0,
+ bwidth / 2,
+ UI_UNIT_Y,
+ cp,
+ -UI_FLT_MAX,
+ UI_FLT_MAX,
+ 10,
+ 3,
+ TIP_("Coefficient for polynomial"));
+
+ /* 'x' param (and '+' if necessary) */
+ if (i == 0)
+ BLI_strncpy(xval, "", sizeof(xval));
+ else if (i == 1)
+ BLI_strncpy(xval, "x", sizeof(xval));
+ else
+ BLI_snprintf(xval, sizeof(xval), "x^%u", i);
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 1,
+ xval,
+ 0,
+ 0,
+ maxXWidth,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ TIP_("Power of x"));
+
+ if ((i != (data->arraysize - 1)) || ((i == 0) && data->arraysize == 2)) {
+ uiDefBut(
+ block, UI_BTYPE_LABEL, 1, "+", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+
+ /* next coefficient on a new row */
+ row = uiLayoutRow(layout, true);
+ block = uiLayoutGetBlock(row);
+ }
+ else {
+ /* For alignment in UI! */
+ uiDefBut(
+ block, UI_BTYPE_LABEL, 1, " ", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+ }
+ }
+ break;
+ }
+
+ case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial expression */
+ {
+ float *cp = NULL;
+ unsigned int i;
+
+ /* draw polynomial order selector */
+ row = uiLayoutRow(layout, false);
+ block = uiLayoutGetBlock(row);
+ but = uiDefButI(
+ block,
+ UI_BTYPE_NUM,
+ B_FMODIFIER_REDRAW,
+ IFACE_("Poly Order:"),
+ 0,
+ 0,
+ width - 1.5 * UI_UNIT_X,
+ UI_UNIT_Y,
+ &data->poly_order,
+ 1,
+ 100,
+ 0,
+ 0,
+ TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
+ UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
+
+ /* draw controls for each pair of coefficients */
+ row = uiLayoutRow(layout, true);
+ block = uiLayoutGetBlock(row);
+
+ cp = data->coefficients;
+ for (i = 0; (i < data->poly_order) && (cp); i++, cp += 2) {
+ /* To align with first line */
+ if (i)
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 1,
+ " ",
+ 0,
+ 0,
+ 2.5 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ else
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 1,
+ "y =",
+ 0,
+ 0,
+ 2.5 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ /* opening bracket */
+ uiDefBut(
+ block, UI_BTYPE_LABEL, 1, "(", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
+
+ /* coefficients */
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_FMODIFIER_REDRAW,
+ "",
+ 0,
+ 0,
+ 5 * UI_UNIT_X,
+ UI_UNIT_Y,
+ cp,
+ -UI_FLT_MAX,
+ UI_FLT_MAX,
+ 10,
+ 3,
+ TIP_("Coefficient of x"));
+
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 1,
+ "x +",
+ 0,
+ 0,
+ 2 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_FMODIFIER_REDRAW,
+ "",
+ 0,
+ 0,
+ 5 * UI_UNIT_X,
+ UI_UNIT_Y,
+ cp + 1,
+ -UI_FLT_MAX,
+ UI_FLT_MAX,
+ 10,
+ 3,
+ TIP_("Second coefficient"));
+
+ /* closing bracket and multiplication sign */
+ if ((i != (data->poly_order - 1)) || ((i == 0) && data->poly_order == 2)) {
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 1,
+ ") \xc3\x97",
+ 0,
+ 0,
+ 2 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+
+ /* set up new row for the next pair of coefficients */
+ row = uiLayoutRow(layout, true);
+ block = uiLayoutGetBlock(row);
+ }
+ else
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 1,
+ ") ",
+ 0,
+ 0,
+ 2 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+ }
+ break;
+ }
+ }
}
/* --------------- */
/* draw settings for generator modifier */
-static void draw_modifier__fn_generator(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short UNUSED(width))
+static void draw_modifier__fn_generator(uiLayout *layout,
+ ID *fcurve_owner_id,
+ FModifier *fcm,
+ short UNUSED(width))
{
- uiLayout *col;
- PointerRNA ptr;
-
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
-
- /* add the settings */
- col = uiLayoutColumn(layout, true);
- uiItemR(col, &ptr, "function_type", 0, "", ICON_NONE);
- uiItemR(col, &ptr, "use_additive", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
-
- col = uiLayoutColumn(layout, false); // no grouping for now
- uiItemR(col, &ptr, "amplitude", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "phase_multiplier", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "phase_offset", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "value_offset", 0, NULL, ICON_NONE);
+ uiLayout *col;
+ PointerRNA ptr;
+
+ /* init the RNA-pointer */
+ RNA_pointer_create(fcurve_owner_id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
+
+ /* add the settings */
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, &ptr, "function_type", 0, "", ICON_NONE);
+ uiItemR(col, &ptr, "use_additive", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
+
+ col = uiLayoutColumn(layout, false); // no grouping for now
+ uiItemR(col, &ptr, "amplitude", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "phase_multiplier", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "phase_offset", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "value_offset", 0, NULL, ICON_NONE);
}
/* --------------- */
/* draw settings for cycles modifier */
-static void draw_modifier__cycles(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short UNUSED(width))
+static void draw_modifier__cycles(uiLayout *layout,
+ ID *fcurve_owner_id,
+ FModifier *fcm,
+ short UNUSED(width))
{
- uiLayout *split, *col;
- PointerRNA ptr;
-
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierCycles, fcm, &ptr);
-
- /* split into 2 columns
- * NOTE: the mode comboboxes shouldn't get labels, otherwise there isn't enough room
- */
- split = uiLayoutSplit(layout, 0.5f, false);
-
- /* before range */
- col = uiLayoutColumn(split, true);
- uiItemL(col, IFACE_("Before:"), ICON_NONE);
- uiItemR(col, &ptr, "mode_before", 0, "", ICON_NONE);
- uiItemR(col, &ptr, "cycles_before", 0, NULL, ICON_NONE);
-
- /* after range */
- col = uiLayoutColumn(split, true);
- uiItemL(col, IFACE_("After:"), ICON_NONE);
- uiItemR(col, &ptr, "mode_after", 0, "", ICON_NONE);
- uiItemR(col, &ptr, "cycles_after", 0, NULL, ICON_NONE);
+ uiLayout *split, *col;
+ PointerRNA ptr;
+
+ /* init the RNA-pointer */
+ RNA_pointer_create(fcurve_owner_id, &RNA_FModifierCycles, fcm, &ptr);
+
+ /* split into 2 columns
+ * NOTE: the mode comboboxes shouldn't get labels, otherwise there isn't enough room
+ */
+ split = uiLayoutSplit(layout, 0.5f, false);
+
+ /* before range */
+ col = uiLayoutColumn(split, true);
+ uiItemL(col, IFACE_("Before:"), ICON_NONE);
+ uiItemR(col, &ptr, "mode_before", 0, "", ICON_NONE);
+ uiItemR(col, &ptr, "cycles_before", 0, NULL, ICON_NONE);
+
+ /* after range */
+ col = uiLayoutColumn(split, true);
+ uiItemL(col, IFACE_("After:"), ICON_NONE);
+ uiItemR(col, &ptr, "mode_after", 0, "", ICON_NONE);
+ uiItemR(col, &ptr, "cycles_after", 0, NULL, ICON_NONE);
}
/* --------------- */
/* draw settings for noise modifier */
-static void draw_modifier__noise(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short UNUSED(width))
+static void draw_modifier__noise(uiLayout *layout,
+ ID *fcurve_owner_id,
+ FModifier *fcm,
+ short UNUSED(width))
{
- uiLayout *split, *col;
- PointerRNA ptr;
+ uiLayout *split, *col;
+ PointerRNA ptr;
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierNoise, fcm, &ptr);
+ /* init the RNA-pointer */
+ RNA_pointer_create(fcurve_owner_id, &RNA_FModifierNoise, fcm, &ptr);
- /* blending mode */
- uiItemR(layout, &ptr, "blend_type", 0, NULL, ICON_NONE);
+ /* blending mode */
+ uiItemR(layout, &ptr, "blend_type", 0, NULL, ICON_NONE);
- /* split into 2 columns */
- split = uiLayoutSplit(layout, 0.5f, false);
+ /* split into 2 columns */
+ split = uiLayoutSplit(layout, 0.5f, false);
- /* col 1 */
- col = uiLayoutColumn(split, false);
- uiItemR(col, &ptr, "scale", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "strength", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "offset", 0, NULL, ICON_NONE);
+ /* col 1 */
+ col = uiLayoutColumn(split, false);
+ uiItemR(col, &ptr, "scale", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "strength", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "offset", 0, NULL, ICON_NONE);
- /* col 2 */
- col = uiLayoutColumn(split, false);
- uiItemR(col, &ptr, "phase", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "depth", 0, NULL, ICON_NONE);
+ /* col 2 */
+ col = uiLayoutColumn(split, false);
+ uiItemR(col, &ptr, "phase", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "depth", 0, NULL, ICON_NONE);
}
/* callback to add new envelope data point */
static void fmod_envelope_addpoint_cb(bContext *C, void *fcm_dv, void *UNUSED(arg))
{
- Scene *scene = CTX_data_scene(C);
- FMod_Envelope *env = (FMod_Envelope *)fcm_dv;
- FCM_EnvelopeData *fedn;
- FCM_EnvelopeData fed;
-
- /* init template data */
- fed.min = -1.0f;
- fed.max = 1.0f;
- fed.time = (float)scene->r.cfra; // XXX make this int for ease of use?
- fed.f1 = fed.f2 = 0;
-
- /* check that no data exists for the current frame... */
- if (env->data) {
- bool exists;
- int i = BKE_fcm_envelope_find_index(env->data, (float)(scene->r.cfra), env->totvert, &exists);
-
- /* binarysearch_...() will set exists by default to 0,
- * so if it is non-zero, that means that the point exists already */
- if (exists) {
- return;
- }
-
- /* add new */
- fedn = MEM_callocN((env->totvert + 1) * sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
-
- /* add the points that should occur before the point to be pasted */
- if (i > 0)
- memcpy(fedn, env->data, i * sizeof(FCM_EnvelopeData));
-
- /* add point to paste at index i */
- *(fedn + i) = fed;
-
- /* add the points that occur after the point to be pasted */
- if (i < env->totvert)
- memcpy(fedn + i + 1, env->data + i, (env->totvert - i) * sizeof(FCM_EnvelopeData));
-
- /* replace (+ free) old with new */
- MEM_freeN(env->data);
- env->data = fedn;
-
- env->totvert++;
- }
- else {
- env->data = MEM_callocN(sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
- *(env->data) = fed;
-
- env->totvert = 1;
- }
+ Scene *scene = CTX_data_scene(C);
+ FMod_Envelope *env = (FMod_Envelope *)fcm_dv;
+ FCM_EnvelopeData *fedn;
+ FCM_EnvelopeData fed;
+
+ /* init template data */
+ fed.min = -1.0f;
+ fed.max = 1.0f;
+ fed.time = (float)scene->r.cfra; // XXX make this int for ease of use?
+ fed.f1 = fed.f2 = 0;
+
+ /* check that no data exists for the current frame... */
+ if (env->data) {
+ bool exists;
+ int i = BKE_fcm_envelope_find_index(env->data, (float)(scene->r.cfra), env->totvert, &exists);
+
+ /* binarysearch_...() will set exists by default to 0,
+ * so if it is non-zero, that means that the point exists already */
+ if (exists) {
+ return;
+ }
+
+ /* add new */
+ fedn = MEM_callocN((env->totvert + 1) * sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
+
+ /* add the points that should occur before the point to be pasted */
+ if (i > 0)
+ memcpy(fedn, env->data, i * sizeof(FCM_EnvelopeData));
+
+ /* add point to paste at index i */
+ *(fedn + i) = fed;
+
+ /* add the points that occur after the point to be pasted */
+ if (i < env->totvert)
+ memcpy(fedn + i + 1, env->data + i, (env->totvert - i) * sizeof(FCM_EnvelopeData));
+
+ /* replace (+ free) old with new */
+ MEM_freeN(env->data);
+ env->data = fedn;
+
+ env->totvert++;
+ }
+ else {
+ env->data = MEM_callocN(sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
+ *(env->data) = fed;
+
+ env->totvert = 1;
+ }
}
/* callback to remove envelope data point */
// TODO: should we have a separate file for things like this?
static void fmod_envelope_deletepoint_cb(bContext *UNUSED(C), void *fcm_dv, void *ind_v)
{
- FMod_Envelope *env = (FMod_Envelope *)fcm_dv;
- FCM_EnvelopeData *fedn;
- int index = POINTER_AS_INT(ind_v);
-
- /* check that no data exists for the current frame... */
- if (env->totvert > 1) {
- /* allocate a new smaller array */
- fedn = MEM_callocN(sizeof(FCM_EnvelopeData) * (env->totvert - 1), "FCM_EnvelopeData");
-
- memcpy(fedn, env->data, sizeof(FCM_EnvelopeData) * (index));
- memcpy(fedn + index, env->data + (index + 1), sizeof(FCM_EnvelopeData) * ((env->totvert - index) - 1));
-
- /* free old array, and set the new */
- MEM_freeN(env->data);
- env->data = fedn;
- env->totvert--;
- }
- else {
- /* just free array, since the only vert was deleted */
- if (env->data) {
- MEM_freeN(env->data);
- env->data = NULL;
- }
- env->totvert = 0;
- }
+ FMod_Envelope *env = (FMod_Envelope *)fcm_dv;
+ FCM_EnvelopeData *fedn;
+ int index = POINTER_AS_INT(ind_v);
+
+ /* check that no data exists for the current frame... */
+ if (env->totvert > 1) {
+ /* allocate a new smaller array */
+ fedn = MEM_callocN(sizeof(FCM_EnvelopeData) * (env->totvert - 1), "FCM_EnvelopeData");
+
+ memcpy(fedn, env->data, sizeof(FCM_EnvelopeData) * (index));
+ memcpy(fedn + index,
+ env->data + (index + 1),
+ sizeof(FCM_EnvelopeData) * ((env->totvert - index) - 1));
+
+ /* free old array, and set the new */
+ MEM_freeN(env->data);
+ env->data = fedn;
+ env->totvert--;
+ }
+ else {
+ /* just free array, since the only vert was deleted */
+ if (env->data) {
+ MEM_freeN(env->data);
+ env->data = NULL;
+ }
+ env->totvert = 0;
+ }
}
/* draw settings for envelope modifier */
-static void draw_modifier__envelope(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short UNUSED(width))
+static void draw_modifier__envelope(uiLayout *layout,
+ ID *fcurve_owner_id,
+ FModifier *fcm,
+ short UNUSED(width))
{
- FMod_Envelope *env = (FMod_Envelope *)fcm->data;
- FCM_EnvelopeData *fed;
- uiLayout *col, *row;
- uiBlock *block;
- uiBut *but;
- PointerRNA ptr;
- int i;
-
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierEnvelope, fcm, &ptr);
-
- /* general settings */
- col = uiLayoutColumn(layout, true);
- uiItemL(col, IFACE_("Envelope:"), ICON_NONE);
- uiItemR(col, &ptr, "reference_value", 0, NULL, ICON_NONE);
-
- row = uiLayoutRow(col, true);
- uiItemR(row, &ptr, "default_min", 0, IFACE_("Min"), ICON_NONE);
- uiItemR(row, &ptr, "default_max", 0, IFACE_("Max"), ICON_NONE);
-
- /* control points header */
- /* TODO: move this control-point control stuff to using the new special widgets for lists
- * the current way is far too cramped */
- row = uiLayoutRow(layout, false);
- block = uiLayoutGetBlock(row);
-
- uiDefBut(block, UI_BTYPE_LABEL, 1, IFACE_("Control Points:"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
- but = uiDefBut(block, UI_BTYPE_BUT, B_FMODIFIER_REDRAW, IFACE_("Add Point"), 0, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y,
- NULL, 0, 0, 0, 0, TIP_("Add a new control-point to the envelope on the current frame"));
- UI_but_func_set(but, fmod_envelope_addpoint_cb, env, NULL);
-
- /* control points list */
- for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
- /* get a new row to operate on */
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
-
- UI_block_align_begin(block);
- but = uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Fra:"), 0, 0, 4.5 * UI_UNIT_X, UI_UNIT_Y,
- &fed->time, -MAXFRAMEF, MAXFRAMEF, 10, 1, TIP_("Frame that envelope point occurs"));
- UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
-
- uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Min:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y,
- &fed->min, -UI_FLT_MAX, UI_FLT_MAX, 10, 2, TIP_("Minimum bound of envelope at this point"));
- uiDefButF(block, UI_BTYPE_NUM, B_FMODIFIER_REDRAW, IFACE_("Max:"), 0, 0, 5 * UI_UNIT_X, UI_UNIT_Y,
- &fed->max, -UI_FLT_MAX, UI_FLT_MAX, 10, 2, TIP_("Maximum bound of envelope at this point"));
-
- but = uiDefIconBut(block, UI_BTYPE_BUT, B_FMODIFIER_REDRAW, ICON_X, 0, 0, 0.9 * UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete envelope control point"));
- UI_but_func_set(but, fmod_envelope_deletepoint_cb, env, POINTER_FROM_INT(i));
- UI_block_align_begin(block);
- }
+ FMod_Envelope *env = (FMod_Envelope *)fcm->data;
+ FCM_EnvelopeData *fed;
+ uiLayout *col, *row;
+ uiBlock *block;
+ uiBut *but;
+ PointerRNA ptr;
+ int i;
+
+ /* init the RNA-pointer */
+ RNA_pointer_create(fcurve_owner_id, &RNA_FModifierEnvelope, fcm, &ptr);
+
+ /* general settings */
+ col = uiLayoutColumn(layout, true);
+ uiItemL(col, IFACE_("Envelope:"), ICON_NONE);
+ uiItemR(col, &ptr, "reference_value", 0, NULL, ICON_NONE);
+
+ row = uiLayoutRow(col, true);
+ uiItemR(row, &ptr, "default_min", 0, IFACE_("Min"), ICON_NONE);
+ uiItemR(row, &ptr, "default_max", 0, IFACE_("Max"), ICON_NONE);
+
+ /* control points header */
+ /* TODO: move this control-point control stuff to using the new special widgets for lists
+ * the current way is far too cramped */
+ row = uiLayoutRow(layout, false);
+ block = uiLayoutGetBlock(row);
+
+ uiDefBut(block,
+ UI_BTYPE_LABEL,
+ 1,
+ IFACE_("Control Points:"),
+ 0,
+ 0,
+ 7.5 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ "");
+
+ but = uiDefBut(block,
+ UI_BTYPE_BUT,
+ B_FMODIFIER_REDRAW,
+ IFACE_("Add Point"),
+ 0,
+ 0,
+ 7.5 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Add a new control-point to the envelope on the current frame"));
+ UI_but_func_set(but, fmod_envelope_addpoint_cb, env, NULL);
+
+ /* control points list */
+ for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
+ /* get a new row to operate on */
+ row = uiLayoutRow(layout, true);
+ block = uiLayoutGetBlock(row);
+
+ UI_block_align_begin(block);
+ but = uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_FMODIFIER_REDRAW,
+ IFACE_("Fra:"),
+ 0,
+ 0,
+ 4.5 * UI_UNIT_X,
+ UI_UNIT_Y,
+ &fed->time,
+ -MAXFRAMEF,
+ MAXFRAMEF,
+ 10,
+ 1,
+ TIP_("Frame that envelope point occurs"));
+ UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
+
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_FMODIFIER_REDRAW,
+ IFACE_("Min:"),
+ 0,
+ 0,
+ 5 * UI_UNIT_X,
+ UI_UNIT_Y,
+ &fed->min,
+ -UI_FLT_MAX,
+ UI_FLT_MAX,
+ 10,
+ 2,
+ TIP_("Minimum bound of envelope at this point"));
+ uiDefButF(block,
+ UI_BTYPE_NUM,
+ B_FMODIFIER_REDRAW,
+ IFACE_("Max:"),
+ 0,
+ 0,
+ 5 * UI_UNIT_X,
+ UI_UNIT_Y,
+ &fed->max,
+ -UI_FLT_MAX,
+ UI_FLT_MAX,
+ 10,
+ 2,
+ TIP_("Maximum bound of envelope at this point"));
+
+ but = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ B_FMODIFIER_REDRAW,
+ ICON_X,
+ 0,
+ 0,
+ 0.9 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Delete envelope control point"));
+ UI_but_func_set(but, fmod_envelope_deletepoint_cb, env, POINTER_FROM_INT(i));
+ UI_block_align_begin(block);
+ }
}
/* --------------- */
/* draw settings for limits modifier */
-static void draw_modifier__limits(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short UNUSED(width))
+static void draw_modifier__limits(uiLayout *layout,
+ ID *fcurve_owner_id,
+ FModifier *fcm,
+ short UNUSED(width))
{
- uiLayout *split, *col /* , *row */ /* UNUSED */;
- PointerRNA ptr;
-
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierLimits, fcm, &ptr);
-
- /* row 1: minimum */
- {
- /* row = uiLayoutRow(layout, false); */ /* UNUSED */
-
- /* split into 2 columns */
- split = uiLayoutSplit(layout, 0.5f, false);
-
- /* x-minimum */
- col = uiLayoutColumn(split, true);
- uiItemR(col, &ptr, "use_min_x", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "min_x", 0, NULL, ICON_NONE);
-
- /* y-minimum*/
- col = uiLayoutColumn(split, true);
- uiItemR(col, &ptr, "use_min_y", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "min_y", 0, NULL, ICON_NONE);
- }
-
- /* row 2: maximum */
- {
- /* row = uiLayoutRow(layout, false); */ /* UNUSED */
-
- /* split into 2 columns */
- split = uiLayoutSplit(layout, 0.5f, false);
-
- /* x-minimum */
- col = uiLayoutColumn(split, true);
- uiItemR(col, &ptr, "use_max_x", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "max_x", 0, NULL, ICON_NONE);
-
- /* y-minimum*/
- col = uiLayoutColumn(split, true);
- uiItemR(col, &ptr, "use_max_y", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "max_y", 0, NULL, ICON_NONE);
- }
+ uiLayout *split, *col /* , *row */ /* UNUSED */;
+ PointerRNA ptr;
+
+ /* init the RNA-pointer */
+ RNA_pointer_create(fcurve_owner_id, &RNA_FModifierLimits, fcm, &ptr);
+
+ /* row 1: minimum */
+ {
+ /* row = uiLayoutRow(layout, false); */ /* UNUSED */
+
+ /* split into 2 columns */
+ split = uiLayoutSplit(layout, 0.5f, false);
+
+ /* x-minimum */
+ col = uiLayoutColumn(split, true);
+ uiItemR(col, &ptr, "use_min_x", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "min_x", 0, NULL, ICON_NONE);
+
+ /* y-minimum*/
+ col = uiLayoutColumn(split, true);
+ uiItemR(col, &ptr, "use_min_y", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "min_y", 0, NULL, ICON_NONE);
+ }
+
+ /* row 2: maximum */
+ {
+ /* row = uiLayoutRow(layout, false); */ /* UNUSED */
+
+ /* split into 2 columns */
+ split = uiLayoutSplit(layout, 0.5f, false);
+
+ /* x-minimum */
+ col = uiLayoutColumn(split, true);
+ uiItemR(col, &ptr, "use_max_x", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "max_x", 0, NULL, ICON_NONE);
+
+ /* y-minimum*/
+ col = uiLayoutColumn(split, true);
+ uiItemR(col, &ptr, "use_max_y", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "max_y", 0, NULL, ICON_NONE);
+ }
}
/* --------------- */
/* draw settings for stepped interpolation modifier */
-static void draw_modifier__stepped(uiLayout *layout, ID *fcurve_owner_id, FModifier *fcm, short UNUSED(width))
+static void draw_modifier__stepped(uiLayout *layout,
+ ID *fcurve_owner_id,
+ FModifier *fcm,
+ short UNUSED(width))
{
- uiLayout *col, *sub;
- PointerRNA ptr;
+ uiLayout *col, *sub;
+ PointerRNA ptr;
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierStepped, fcm, &ptr);
+ /* init the RNA-pointer */
+ RNA_pointer_create(fcurve_owner_id, &RNA_FModifierStepped, fcm, &ptr);
- /* block 1: "stepping" settings */
- col = uiLayoutColumn(layout, false);
- uiItemR(col, &ptr, "frame_step", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "frame_offset", 0, NULL, ICON_NONE);
+ /* block 1: "stepping" settings */
+ col = uiLayoutColumn(layout, false);
+ uiItemR(col, &ptr, "frame_step", 0, NULL, ICON_NONE);
+ uiItemR(col, &ptr, "frame_offset", 0, NULL, ICON_NONE);
- /* block 2: start range settings */
- col = uiLayoutColumn(layout, true);
- uiItemR(col, &ptr, "use_frame_start", 0, NULL, ICON_NONE);
+ /* block 2: start range settings */
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, &ptr, "use_frame_start", 0, NULL, ICON_NONE);
- sub = uiLayoutColumn(col, true);
- uiLayoutSetActive(sub, RNA_boolean_get(&ptr, "use_frame_start"));
- uiItemR(sub, &ptr, "frame_start", 0, NULL, ICON_NONE);
+ sub = uiLayoutColumn(col, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(&ptr, "use_frame_start"));
+ uiItemR(sub, &ptr, "frame_start", 0, NULL, ICON_NONE);
- /* block 3: end range settings */
- col = uiLayoutColumn(layout, true);
- uiItemR(col, &ptr, "use_frame_end", 0, NULL, ICON_NONE);
+ /* block 3: end range settings */
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, &ptr, "use_frame_end", 0, NULL, ICON_NONE);
- sub = uiLayoutColumn(col, true);
- uiLayoutSetActive(sub, RNA_boolean_get(&ptr, "use_frame_end"));
- uiItemR(sub, &ptr, "frame_end", 0, NULL, ICON_NONE);
+ sub = uiLayoutColumn(col, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(&ptr, "use_frame_end"));
+ uiItemR(sub, &ptr, "frame_end", 0, NULL, ICON_NONE);
}
/* --------------- */
-void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout, ID *fcurve_owner_id,
- ListBase *modifiers, FModifier *fcm)
+void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout,
+ ID *fcurve_owner_id,
+ ListBase *modifiers,
+ FModifier *fcm)
{
- const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
- uiLayout *box, *row, *sub, *col;
- uiBlock *block;
- uiBut *but;
- short width = 314;
- PointerRNA ptr;
-
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifier, fcm, &ptr);
-
- /* draw header */
- {
- /* get layout-row + UI-block for this */
- box = uiLayoutBox(layout);
-
- row = uiLayoutRow(box, false);
- block = uiLayoutGetBlock(row); // err...
-
- /* left-align -------------------------------------------- */
- sub = uiLayoutRow(row, true);
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
- /* expand */
- uiItemR(sub, &ptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
-
- /* checkbox for 'active' status (for now) */
- uiItemR(sub, &ptr, "active", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
-
- /* name */
- if (fmi)
- uiItemL(sub, IFACE_(fmi->name), ICON_NONE);
- else
- uiItemL(sub, IFACE_("<Unknown Modifier>"), ICON_NONE);
-
- /* right-align ------------------------------------------- */
- sub = uiLayoutRow(row, true);
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
-
-
- /* 'mute' button */
- uiItemR(sub, &ptr, "mute", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
- /* delete button */
- but = uiDefIconBut(block, UI_BTYPE_BUT, B_REDR, ICON_X, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, TIP_("Delete F-Curve Modifier"));
- FModifierDeleteContext *ctx = MEM_mallocN(sizeof(FModifierDeleteContext), "fmodifier ctx");
- ctx->fcurve_owner_id = fcurve_owner_id;
- ctx->modifiers = modifiers;
- UI_but_funcN_set(but, delete_fmodifier_cb, ctx, fcm);
-
- UI_block_emboss_set(block, UI_EMBOSS);
- }
-
- /* when modifier is expanded, draw settings */
- if (fcm->flag & FMODIFIER_FLAG_EXPANDED) {
- /* set up the flexible-box layout which acts as the backdrop for the modifier settings */
- box = uiLayoutBox(layout);
-
- /* draw settings for individual modifiers */
- switch (fcm->type) {
- case FMODIFIER_TYPE_GENERATOR: /* Generator */
- draw_modifier__generator(box, fcurve_owner_id, fcm, width);
- break;
-
- case FMODIFIER_TYPE_FN_GENERATOR: /* Built-In Function Generator */
- draw_modifier__fn_generator(box, fcurve_owner_id, fcm, width);
- break;
-
- case FMODIFIER_TYPE_CYCLES: /* Cycles */
- draw_modifier__cycles(box, fcurve_owner_id, fcm, width);
- break;
-
- case FMODIFIER_TYPE_ENVELOPE: /* Envelope */
- draw_modifier__envelope(box, fcurve_owner_id, fcm, width);
- break;
-
- case FMODIFIER_TYPE_LIMITS: /* Limits */
- draw_modifier__limits(box, fcurve_owner_id, fcm, width);
- break;
-
- case FMODIFIER_TYPE_NOISE: /* Noise */
- draw_modifier__noise(box, fcurve_owner_id, fcm, width);
- break;
-
- case FMODIFIER_TYPE_STEPPED: /* Stepped */
- draw_modifier__stepped(box, fcurve_owner_id, fcm, width);
- break;
-
- default: /* unknown type */
- break;
- }
-
- /* one last panel below this: FModifier range */
- // TODO: experiment with placement of this
- {
- box = uiLayoutBox(layout);
-
- /* restricted range ----------------------------------------------------- */
- col = uiLayoutColumn(box, true);
-
- /* top row: use restricted range */
- row = uiLayoutRow(col, true);
- uiItemR(row, &ptr, "use_restricted_range", 0, NULL, ICON_NONE);
-
- if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
- /* second row: settings */
- row = uiLayoutRow(col, true);
-
- uiItemR(row, &ptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
- uiItemR(row, &ptr, "frame_end", 0, IFACE_("End"), ICON_NONE);
-
- /* third row: blending influence */
- row = uiLayoutRow(col, true);
-
- uiItemR(row, &ptr, "blend_in", 0, IFACE_("In"), ICON_NONE);
- uiItemR(row, &ptr, "blend_out", 0, IFACE_("Out"), ICON_NONE);
- }
-
- /* influence -------------------------------------------------------------- */
- col = uiLayoutColumn(box, true);
-
- /* top row: use influence */
- uiItemR(col, &ptr, "use_influence", 0, NULL, ICON_NONE);
-
- if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE) {
- /* second row: influence value */
- uiItemR(col, &ptr, "influence", 0, NULL, ICON_NONE);
- }
- }
- }
+ const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
+ uiLayout *box, *row, *sub, *col;
+ uiBlock *block;
+ uiBut *but;
+ short width = 314;
+ PointerRNA ptr;
+
+ /* init the RNA-pointer */
+ RNA_pointer_create(fcurve_owner_id, &RNA_FModifier, fcm, &ptr);
+
+ /* draw header */
+ {
+ /* get layout-row + UI-block for this */
+ box = uiLayoutBox(layout);
+
+ row = uiLayoutRow(box, false);
+ block = uiLayoutGetBlock(row); // err...
+
+ /* left-align -------------------------------------------- */
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+
+ /* expand */
+ uiItemR(sub, &ptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+
+ /* checkbox for 'active' status (for now) */
+ uiItemR(sub, &ptr, "active", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+
+ /* name */
+ if (fmi)
+ uiItemL(sub, IFACE_(fmi->name), ICON_NONE);
+ else
+ uiItemL(sub, IFACE_("<Unknown Modifier>"), ICON_NONE);
+
+ /* right-align ------------------------------------------- */
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
+
+ /* 'mute' button */
+ uiItemR(sub, &ptr, "mute", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+
+ /* delete button */
+ but = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ B_REDR,
+ ICON_X,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Delete F-Curve Modifier"));
+ FModifierDeleteContext *ctx = MEM_mallocN(sizeof(FModifierDeleteContext), "fmodifier ctx");
+ ctx->fcurve_owner_id = fcurve_owner_id;
+ ctx->modifiers = modifiers;
+ UI_but_funcN_set(but, delete_fmodifier_cb, ctx, fcm);
+
+ UI_block_emboss_set(block, UI_EMBOSS);
+ }
+
+ /* when modifier is expanded, draw settings */
+ if (fcm->flag & FMODIFIER_FLAG_EXPANDED) {
+ /* set up the flexible-box layout which acts as the backdrop for the modifier settings */
+ box = uiLayoutBox(layout);
+
+ /* draw settings for individual modifiers */
+ switch (fcm->type) {
+ case FMODIFIER_TYPE_GENERATOR: /* Generator */
+ draw_modifier__generator(box, fcurve_owner_id, fcm, width);
+ break;
+
+ case FMODIFIER_TYPE_FN_GENERATOR: /* Built-In Function Generator */
+ draw_modifier__fn_generator(box, fcurve_owner_id, fcm, width);
+ break;
+
+ case FMODIFIER_TYPE_CYCLES: /* Cycles */
+ draw_modifier__cycles(box, fcurve_owner_id, fcm, width);
+ break;
+
+ case FMODIFIER_TYPE_ENVELOPE: /* Envelope */
+ draw_modifier__envelope(box, fcurve_owner_id, fcm, width);
+ break;
+
+ case FMODIFIER_TYPE_LIMITS: /* Limits */
+ draw_modifier__limits(box, fcurve_owner_id, fcm, width);
+ break;
+
+ case FMODIFIER_TYPE_NOISE: /* Noise */
+ draw_modifier__noise(box, fcurve_owner_id, fcm, width);
+ break;
+
+ case FMODIFIER_TYPE_STEPPED: /* Stepped */
+ draw_modifier__stepped(box, fcurve_owner_id, fcm, width);
+ break;
+
+ default: /* unknown type */
+ break;
+ }
+
+ /* one last panel below this: FModifier range */
+ // TODO: experiment with placement of this
+ {
+ box = uiLayoutBox(layout);
+
+ /* restricted range ----------------------------------------------------- */
+ col = uiLayoutColumn(box, true);
+
+ /* top row: use restricted range */
+ row = uiLayoutRow(col, true);
+ uiItemR(row, &ptr, "use_restricted_range", 0, NULL, ICON_NONE);
+
+ if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
+ /* second row: settings */
+ row = uiLayoutRow(col, true);
+
+ uiItemR(row, &ptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
+ uiItemR(row, &ptr, "frame_end", 0, IFACE_("End"), ICON_NONE);
+
+ /* third row: blending influence */
+ row = uiLayoutRow(col, true);
+
+ uiItemR(row, &ptr, "blend_in", 0, IFACE_("In"), ICON_NONE);
+ uiItemR(row, &ptr, "blend_out", 0, IFACE_("Out"), ICON_NONE);
+ }
+
+ /* influence -------------------------------------------------------------- */
+ col = uiLayoutColumn(box, true);
+
+ /* top row: use influence */
+ uiItemR(col, &ptr, "use_influence", 0, NULL, ICON_NONE);
+
+ if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE) {
+ /* second row: influence value */
+ uiItemR(col, &ptr, "influence", 0, NULL, ICON_NONE);
+ }
+ }
+ }
}
/* ********************************************** */
@@ -707,8 +1010,8 @@ static ListBase fmodifier_copypaste_buf = {NULL, NULL};
/* free the copy/paste buffer */
void ANIM_fmodifiers_copybuf_free(void)
{
- /* just free the whole buffer */
- free_fmodifiers(&fmodifier_copypaste_buf);
+ /* just free the whole buffer */
+ free_fmodifiers(&fmodifier_copypaste_buf);
}
/* copy the given F-Modifiers to the buffer, returning whether anything was copied or not
@@ -717,28 +1020,28 @@ void ANIM_fmodifiers_copybuf_free(void)
*/
bool ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, bool active)
{
- bool ok = true;
-
- /* sanity checks */
- if (ELEM(NULL, modifiers, modifiers->first))
- return 0;
-
- /* copy the whole list, or just the active one? */
- if (active) {
- FModifier *fcm = find_active_fmodifier(modifiers);
-
- if (fcm) {
- FModifier *fcmN = copy_fmodifier(fcm);
- BLI_addtail(&fmodifier_copypaste_buf, fcmN);
- }
- else
- ok = 0;
- }
- else
- copy_fmodifiers(&fmodifier_copypaste_buf, modifiers);
-
- /* did we succeed? */
- return ok;
+ bool ok = true;
+
+ /* sanity checks */
+ if (ELEM(NULL, modifiers, modifiers->first))
+ return 0;
+
+ /* copy the whole list, or just the active one? */
+ if (active) {
+ FModifier *fcm = find_active_fmodifier(modifiers);
+
+ if (fcm) {
+ FModifier *fcmN = copy_fmodifier(fcm);
+ BLI_addtail(&fmodifier_copypaste_buf, fcmN);
+ }
+ else
+ ok = 0;
+ }
+ else
+ copy_fmodifiers(&fmodifier_copypaste_buf, modifiers);
+
+ /* did we succeed? */
+ return ok;
}
/* 'Paste' the F-Modifier(s) from the buffer to the specified list
@@ -746,40 +1049,40 @@ bool ANIM_fmodifiers_copy_to_buf(ListBase *modifiers, bool active)
*/
bool ANIM_fmodifiers_paste_from_buf(ListBase *modifiers, bool replace, FCurve *curve)
{
- FModifier *fcm;
- bool ok = false;
+ FModifier *fcm;
+ bool ok = false;
- /* sanity checks */
- if (modifiers == NULL)
- return 0;
+ /* sanity checks */
+ if (modifiers == NULL)
+ return 0;
- bool was_cyclic = curve && BKE_fcurve_is_cyclic(curve);
+ bool was_cyclic = curve && BKE_fcurve_is_cyclic(curve);
- /* if replacing the list, free the existing modifiers */
- if (replace)
- free_fmodifiers(modifiers);
+ /* if replacing the list, free the existing modifiers */
+ if (replace)
+ free_fmodifiers(modifiers);
- /* now copy over all the modifiers in the buffer to the end of the list */
- for (fcm = fmodifier_copypaste_buf.first; fcm; fcm = fcm->next) {
- /* make a copy of it */
- FModifier *fcmN = copy_fmodifier(fcm);
+ /* now copy over all the modifiers in the buffer to the end of the list */
+ for (fcm = fmodifier_copypaste_buf.first; fcm; fcm = fcm->next) {
+ /* make a copy of it */
+ FModifier *fcmN = copy_fmodifier(fcm);
- fcmN->curve = curve;
+ fcmN->curve = curve;
- /* make sure the new one isn't active, otherwise the list may get several actives */
- fcmN->flag &= ~FMODIFIER_FLAG_ACTIVE;
+ /* make sure the new one isn't active, otherwise the list may get several actives */
+ fcmN->flag &= ~FMODIFIER_FLAG_ACTIVE;
- /* now add it to the end of the list */
- BLI_addtail(modifiers, fcmN);
- ok = 1;
- }
+ /* now add it to the end of the list */
+ BLI_addtail(modifiers, fcmN);
+ ok = 1;
+ }
- /* adding or removing the Cycles modifier requires an update to handles */
- if (curve && BKE_fcurve_is_cyclic(curve) != was_cyclic)
- calchandles_fcurve(curve);
+ /* adding or removing the Cycles modifier requires an update to handles */
+ if (curve && BKE_fcurve_is_cyclic(curve) != was_cyclic)
+ calchandles_fcurve(curve);
- /* did we succeed? */
- return ok;
+ /* did we succeed? */
+ return ok;
}
/* ********************************************** */
diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c
index 19ac0ea18a0..e8c17e10b17 100644
--- a/source/blender/editors/animation/keyframes_draw.c
+++ b/source/blender/editors/animation/keyframes_draw.c
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
/* System includes ----------------------------------------------------- */
#include <math.h>
@@ -62,60 +61,60 @@
BLI_INLINE bool is_cfra_eq(float a, float b)
{
- return IS_EQT(a, b, BEZT_BINARYSEARCH_THRESH);
+ return IS_EQT(a, b, BEZT_BINARYSEARCH_THRESH);
}
BLI_INLINE bool is_cfra_lt(float a, float b)
{
- return (b - a) > BEZT_BINARYSEARCH_THRESH;
+ return (b - a) > BEZT_BINARYSEARCH_THRESH;
}
/* Comparator callback used for ActKeyColumns and cframe float-value pointer */
/* NOTE: this is exported to other modules that use the ActKeyColumns for finding keyframes */
short compare_ak_cfraPtr(void *node, void *data)
{
- ActKeyColumn *ak = (ActKeyColumn *)node;
- const float *cframe = data;
- float val = *cframe;
+ ActKeyColumn *ak = (ActKeyColumn *)node;
+ const float *cframe = data;
+ float val = *cframe;
- if (is_cfra_eq(val, ak->cfra))
- return 0;
+ if (is_cfra_eq(val, ak->cfra))
+ return 0;
- if (val < ak->cfra)
- return -1;
- else
- return 1;
+ if (val < ak->cfra)
+ return -1;
+ else
+ return 1;
}
/* --------------- */
/* Set of references to three logically adjacent keys. */
typedef struct BezTripleChain {
- /* Current keyframe. */
- BezTriple *cur;
+ /* Current keyframe. */
+ BezTriple *cur;
- /* Logical neighbors. May be NULL. */
- BezTriple *prev, *next;
+ /* Logical neighbors. May be NULL. */
+ BezTriple *prev, *next;
} BezTripleChain;
/* Categorize the interpolation & handle type of the keyframe. */
static eKeyframeHandleDrawOpts bezt_handle_type(BezTriple *bezt)
{
- if (bezt->h1 == HD_AUTO_ANIM && bezt->h2 == HD_AUTO_ANIM) {
- return KEYFRAME_HANDLE_AUTO_CLAMP;
- }
- else if (ELEM(bezt->h1, HD_AUTO_ANIM, HD_AUTO) && ELEM(bezt->h2, HD_AUTO_ANIM, HD_AUTO)) {
- return KEYFRAME_HANDLE_AUTO;
- }
- else if (bezt->h1 == HD_VECT && bezt->h2 == HD_VECT) {
- return KEYFRAME_HANDLE_VECTOR;
- }
- else if (ELEM(HD_FREE, bezt->h1, bezt->h2)) {
- return KEYFRAME_HANDLE_FREE;
- }
- else {
- return KEYFRAME_HANDLE_ALIGNED;
- }
+ if (bezt->h1 == HD_AUTO_ANIM && bezt->h2 == HD_AUTO_ANIM) {
+ return KEYFRAME_HANDLE_AUTO_CLAMP;
+ }
+ else if (ELEM(bezt->h1, HD_AUTO_ANIM, HD_AUTO) && ELEM(bezt->h2, HD_AUTO_ANIM, HD_AUTO)) {
+ return KEYFRAME_HANDLE_AUTO;
+ }
+ else if (bezt->h1 == HD_VECT && bezt->h2 == HD_VECT) {
+ return KEYFRAME_HANDLE_VECTOR;
+ }
+ else if (ELEM(HD_FREE, bezt->h1, bezt->h2)) {
+ return KEYFRAME_HANDLE_FREE;
+ }
+ else {
+ return KEYFRAME_HANDLE_ALIGNED;
+ }
}
/* Determine if the keyframe is an extreme by comparing with neighbors.
@@ -123,113 +122,114 @@ static eKeyframeHandleDrawOpts bezt_handle_type(BezTriple *bezt)
*/
static eKeyframeExtremeDrawOpts bezt_extreme_type(BezTripleChain *chain)
{
- if (chain->prev == NULL && chain->next == NULL) {
- return KEYFRAME_EXTREME_NONE;
- }
-
- /* Keyframe values for the current one and neighbors. */
- float cur_y = chain->cur->vec[1][1];
- float prev_y = cur_y, next_y = cur_y;
-
- if (chain->prev && !IS_EQF(cur_y, chain->prev->vec[1][1])) {
- prev_y = chain->prev->vec[1][1];
- }
- if (chain->next && !IS_EQF(cur_y, chain->next->vec[1][1])) {
- next_y = chain->next->vec[1][1];
- }
-
- /* Static hold. */
- if (prev_y == cur_y && next_y == cur_y) {
- return KEYFRAME_EXTREME_FLAT;
- }
-
- /* Middle of an incline. */
- if ((prev_y < cur_y && next_y > cur_y) || (prev_y > cur_y && next_y < cur_y)) {
- return KEYFRAME_EXTREME_NONE;
- }
-
- /* Bezier handle values for the overshoot check. */
- bool l_bezier = chain->prev && chain->prev->ipo == BEZT_IPO_BEZ;
- bool r_bezier = chain->next && chain->cur->ipo == BEZT_IPO_BEZ;
- float handle_l = l_bezier ? chain->cur->vec[0][1] : cur_y;
- float handle_r = r_bezier ? chain->cur->vec[2][1] : cur_y;
-
- /* Detect extremes. One of the neighbors is allowed to be equal to current. */
- if (prev_y < cur_y || next_y < cur_y) {
- bool is_overshoot = (handle_l > cur_y || handle_r > cur_y);
-
- return KEYFRAME_EXTREME_MAX | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0);
- }
-
- if (prev_y > cur_y || next_y > cur_y) {
- bool is_overshoot = (handle_l < cur_y || handle_r < cur_y);
-
- return KEYFRAME_EXTREME_MIN | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0);
- }
-
- return KEYFRAME_EXTREME_NONE;
+ if (chain->prev == NULL && chain->next == NULL) {
+ return KEYFRAME_EXTREME_NONE;
+ }
+
+ /* Keyframe values for the current one and neighbors. */
+ float cur_y = chain->cur->vec[1][1];
+ float prev_y = cur_y, next_y = cur_y;
+
+ if (chain->prev && !IS_EQF(cur_y, chain->prev->vec[1][1])) {
+ prev_y = chain->prev->vec[1][1];
+ }
+ if (chain->next && !IS_EQF(cur_y, chain->next->vec[1][1])) {
+ next_y = chain->next->vec[1][1];
+ }
+
+ /* Static hold. */
+ if (prev_y == cur_y && next_y == cur_y) {
+ return KEYFRAME_EXTREME_FLAT;
+ }
+
+ /* Middle of an incline. */
+ if ((prev_y < cur_y && next_y > cur_y) || (prev_y > cur_y && next_y < cur_y)) {
+ return KEYFRAME_EXTREME_NONE;
+ }
+
+ /* Bezier handle values for the overshoot check. */
+ bool l_bezier = chain->prev && chain->prev->ipo == BEZT_IPO_BEZ;
+ bool r_bezier = chain->next && chain->cur->ipo == BEZT_IPO_BEZ;
+ float handle_l = l_bezier ? chain->cur->vec[0][1] : cur_y;
+ float handle_r = r_bezier ? chain->cur->vec[2][1] : cur_y;
+
+ /* Detect extremes. One of the neighbors is allowed to be equal to current. */
+ if (prev_y < cur_y || next_y < cur_y) {
+ bool is_overshoot = (handle_l > cur_y || handle_r > cur_y);
+
+ return KEYFRAME_EXTREME_MAX | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0);
+ }
+
+ if (prev_y > cur_y || next_y > cur_y) {
+ bool is_overshoot = (handle_l < cur_y || handle_r < cur_y);
+
+ return KEYFRAME_EXTREME_MIN | (is_overshoot ? KEYFRAME_EXTREME_MIXED : 0);
+ }
+
+ return KEYFRAME_EXTREME_NONE;
}
/* Comparator callback used for ActKeyColumns and BezTripleChain */
static short compare_ak_bezt(void *node, void *data)
{
- BezTripleChain *chain = data;
+ BezTripleChain *chain = data;
- return compare_ak_cfraPtr(node, &chain->cur->vec[1][0]);
+ return compare_ak_cfraPtr(node, &chain->cur->vec[1][0]);
}
/* New node callback used for building ActKeyColumns from BezTripleChain */
static DLRBT_Node *nalloc_ak_bezt(void *data)
{
- ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
- BezTripleChain *chain = data;
- BezTriple *bezt = chain->cur;
+ ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumn");
+ BezTripleChain *chain = data;
+ BezTriple *bezt = chain->cur;
- /* store settings based on state of BezTriple */
- ak->cfra = bezt->vec[1][0];
- ak->sel = BEZT_ISSEL_ANY(bezt) ? SELECT : 0;
- ak->key_type = BEZKEYTYPE(bezt);
- ak->handle_type = bezt_handle_type(bezt);
- ak->extreme_type = bezt_extreme_type(chain);
+ /* store settings based on state of BezTriple */
+ ak->cfra = bezt->vec[1][0];
+ ak->sel = BEZT_ISSEL_ANY(bezt) ? SELECT : 0;
+ ak->key_type = BEZKEYTYPE(bezt);
+ ak->handle_type = bezt_handle_type(bezt);
+ ak->extreme_type = bezt_extreme_type(chain);
- /* count keyframes in this column */
- ak->totkey = 1;
+ /* count keyframes in this column */
+ ak->totkey = 1;
- return (DLRBT_Node *)ak;
+ return (DLRBT_Node *)ak;
}
/* Node updater callback used for building ActKeyColumns from BezTripleChain */
static void nupdate_ak_bezt(void *node, void *data)
{
- ActKeyColumn *ak = node;
- BezTripleChain *chain = data;
- BezTriple *bezt = chain->cur;
-
- /* set selection status and 'touched' status */
- if (BEZT_ISSEL_ANY(bezt)) ak->sel = SELECT;
-
- /* count keyframes in this column */
- ak->totkey++;
-
- /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
- if (BEZKEYTYPE(bezt) == BEZT_KEYTYPE_KEYFRAME)
- ak->key_type = BEZT_KEYTYPE_KEYFRAME;
-
- /* For interpolation type, select the highest value (enum is sorted). */
- ak->handle_type = MAX2(ak->handle_type, bezt_handle_type(bezt));
-
- /* For extremes, detect when combining different states. */
- char new_extreme = bezt_extreme_type(chain);
-
- if (new_extreme != ak->extreme_type) {
- /* Replace the flat status without adding mixed. */
- if (ak->extreme_type == KEYFRAME_EXTREME_FLAT) {
- ak->extreme_type = new_extreme;
- }
- else if (new_extreme != KEYFRAME_EXTREME_FLAT) {
- ak->extreme_type |= (new_extreme | KEYFRAME_EXTREME_MIXED);
- }
- }
+ ActKeyColumn *ak = node;
+ BezTripleChain *chain = data;
+ BezTriple *bezt = chain->cur;
+
+ /* set selection status and 'touched' status */
+ if (BEZT_ISSEL_ANY(bezt))
+ ak->sel = SELECT;
+
+ /* count keyframes in this column */
+ ak->totkey++;
+
+ /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
+ if (BEZKEYTYPE(bezt) == BEZT_KEYTYPE_KEYFRAME)
+ ak->key_type = BEZT_KEYTYPE_KEYFRAME;
+
+ /* For interpolation type, select the highest value (enum is sorted). */
+ ak->handle_type = MAX2(ak->handle_type, bezt_handle_type(bezt));
+
+ /* For extremes, detect when combining different states. */
+ char new_extreme = bezt_extreme_type(chain);
+
+ if (new_extreme != ak->extreme_type) {
+ /* Replace the flat status without adding mixed. */
+ if (ak->extreme_type == KEYFRAME_EXTREME_FLAT) {
+ ak->extreme_type = new_extreme;
+ }
+ else if (new_extreme != KEYFRAME_EXTREME_FLAT) {
+ ak->extreme_type |= (new_extreme | KEYFRAME_EXTREME_MIXED);
+ }
+ }
}
/* ......... */
@@ -237,44 +237,45 @@ static void nupdate_ak_bezt(void *node, void *data)
/* Comparator callback used for ActKeyColumns and GPencil frame */
static short compare_ak_gpframe(void *node, void *data)
{
- bGPDframe *gpf = (bGPDframe *)data;
+ bGPDframe *gpf = (bGPDframe *)data;
- float frame = gpf->framenum;
- return compare_ak_cfraPtr(node, &frame);
+ float frame = gpf->framenum;
+ return compare_ak_cfraPtr(node, &frame);
}
/* New node callback used for building ActKeyColumns from GPencil frames */
static DLRBT_Node *nalloc_ak_gpframe(void *data)
{
- ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
- bGPDframe *gpf = (bGPDframe *)data;
+ ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
+ bGPDframe *gpf = (bGPDframe *)data;
- /* store settings based on state of BezTriple */
- ak->cfra = gpf->framenum;
- ak->sel = (gpf->flag & GP_FRAME_SELECT) ? SELECT : 0;
- ak->key_type = gpf->key_type;
+ /* store settings based on state of BezTriple */
+ ak->cfra = gpf->framenum;
+ ak->sel = (gpf->flag & GP_FRAME_SELECT) ? SELECT : 0;
+ ak->key_type = gpf->key_type;
- /* count keyframes in this column */
- ak->totkey = 1;
+ /* count keyframes in this column */
+ ak->totkey = 1;
- return (DLRBT_Node *)ak;
+ return (DLRBT_Node *)ak;
}
/* Node updater callback used for building ActKeyColumns from GPencil frames */
static void nupdate_ak_gpframe(void *node, void *data)
{
- ActKeyColumn *ak = (ActKeyColumn *)node;
- bGPDframe *gpf = (bGPDframe *)data;
+ ActKeyColumn *ak = (ActKeyColumn *)node;
+ bGPDframe *gpf = (bGPDframe *)data;
- /* set selection status and 'touched' status */
- if (gpf->flag & GP_FRAME_SELECT) ak->sel = SELECT;
+ /* set selection status and 'touched' status */
+ if (gpf->flag & GP_FRAME_SELECT)
+ ak->sel = SELECT;
- /* count keyframes in this column */
- ak->totkey++;
+ /* count keyframes in this column */
+ ak->totkey++;
- /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
- if (gpf->key_type == BEZT_KEYTYPE_KEYFRAME)
- ak->key_type = BEZT_KEYTYPE_KEYFRAME;
+ /* for keyframe type, 'proper' keyframes have priority over breakdowns (and other types for now) */
+ if (gpf->key_type == BEZT_KEYTYPE_KEYFRAME)
+ ak->key_type = BEZT_KEYTYPE_KEYFRAME;
}
/* ......... */
@@ -282,193 +283,198 @@ static void nupdate_ak_gpframe(void *node, void *data)
/* Comparator callback used for ActKeyColumns and GPencil frame */
static short compare_ak_masklayshape(void *node, void *data)
{
- MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
+ MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
- float frame = masklay_shape->frame;
- return compare_ak_cfraPtr(node, &frame);
+ float frame = masklay_shape->frame;
+ return compare_ak_cfraPtr(node, &frame);
}
/* New node callback used for building ActKeyColumns from GPencil frames */
static DLRBT_Node *nalloc_ak_masklayshape(void *data)
{
- ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
- MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
+ ActKeyColumn *ak = MEM_callocN(sizeof(ActKeyColumn), "ActKeyColumnGPF");
+ MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
- /* store settings based on state of BezTriple */
- ak->cfra = masklay_shape->frame;
- ak->sel = (masklay_shape->flag & MASK_SHAPE_SELECT) ? SELECT : 0;
+ /* store settings based on state of BezTriple */
+ ak->cfra = masklay_shape->frame;
+ ak->sel = (masklay_shape->flag & MASK_SHAPE_SELECT) ? SELECT : 0;
- /* count keyframes in this column */
- ak->totkey = 1;
+ /* count keyframes in this column */
+ ak->totkey = 1;
- return (DLRBT_Node *)ak;
+ return (DLRBT_Node *)ak;
}
/* Node updater callback used for building ActKeyColumns from GPencil frames */
static void nupdate_ak_masklayshape(void *node, void *data)
{
- ActKeyColumn *ak = (ActKeyColumn *)node;
- MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
+ ActKeyColumn *ak = (ActKeyColumn *)node;
+ MaskLayerShape *masklay_shape = (MaskLayerShape *)data;
- /* set selection status and 'touched' status */
- if (masklay_shape->flag & MASK_SHAPE_SELECT) ak->sel = SELECT;
+ /* set selection status and 'touched' status */
+ if (masklay_shape->flag & MASK_SHAPE_SELECT)
+ ak->sel = SELECT;
- /* count keyframes in this column */
- ak->totkey++;
+ /* count keyframes in this column */
+ ak->totkey++;
}
-
/* --------------- */
/* Add the given BezTriple to the given 'list' of Keyframes */
static void add_bezt_to_keycolumns_list(DLRBT_Tree *keys, BezTripleChain *bezt)
{
- if (ELEM(NULL, keys, bezt))
- return;
- else
- BLI_dlrbTree_add(keys, compare_ak_bezt, nalloc_ak_bezt, nupdate_ak_bezt, bezt);
+ if (ELEM(NULL, keys, bezt))
+ return;
+ else
+ BLI_dlrbTree_add(keys, compare_ak_bezt, nalloc_ak_bezt, nupdate_ak_bezt, bezt);
}
/* Add the given GPencil Frame to the given 'list' of Keyframes */
static void add_gpframe_to_keycolumns_list(DLRBT_Tree *keys, bGPDframe *gpf)
{
- if (ELEM(NULL, keys, gpf))
- return;
- else
- BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf);
+ if (ELEM(NULL, keys, gpf))
+ return;
+ else
+ BLI_dlrbTree_add(keys, compare_ak_gpframe, nalloc_ak_gpframe, nupdate_ak_gpframe, gpf);
}
/* Add the given MaskLayerShape Frame to the given 'list' of Keyframes */
static void add_masklay_to_keycolumns_list(DLRBT_Tree *keys, MaskLayerShape *masklay_shape)
{
- if (ELEM(NULL, keys, masklay_shape))
- return;
- else
- BLI_dlrbTree_add(keys, compare_ak_masklayshape, nalloc_ak_masklayshape, nupdate_ak_masklayshape, masklay_shape);
+ if (ELEM(NULL, keys, masklay_shape))
+ return;
+ else
+ BLI_dlrbTree_add(keys,
+ compare_ak_masklayshape,
+ nalloc_ak_masklayshape,
+ nupdate_ak_masklayshape,
+ masklay_shape);
}
/* ActKeyBlocks (Long Keyframes) ------------------------------------------ */
-static const ActKeyBlockInfo dummy_keyblock = { 0 };
+static const ActKeyBlockInfo dummy_keyblock = {0};
static void compute_keyblock_data(ActKeyBlockInfo *info, BezTriple *prev, BezTriple *beztn)
{
- memset(info, 0, sizeof(ActKeyBlockInfo));
-
- if (BEZKEYTYPE(beztn) == BEZT_KEYTYPE_MOVEHOLD) {
- /* Animator tagged a "moving hold"
- * - Previous key must also be tagged as a moving hold, otherwise
- * we're just dealing with the first of a pair, and we don't
- * want to be creating any phantom holds...
- */
- if (BEZKEYTYPE(prev) == BEZT_KEYTYPE_MOVEHOLD) {
- info->flag |= ACTKEYBLOCK_FLAG_MOVING_HOLD | ACTKEYBLOCK_FLAG_ANY_HOLD;
- }
- }
-
- /* Check for same values...
- * - Handles must have same central value as each other
- * - Handles which control that section of the curve must be constant
- */
- if (IS_EQF(beztn->vec[1][1], prev->vec[1][1])) {
- bool hold;
-
- /* Only check handles in case of actual bezier interpolation. */
- if (prev->ipo == BEZT_IPO_BEZ) {
- hold = IS_EQF(beztn->vec[1][1], beztn->vec[0][1]) && IS_EQF(prev->vec[1][1], prev->vec[2][1]);
- }
- /* This interpolation type induces movement even between identical keys. */
- else {
- hold = !ELEM(prev->ipo, BEZT_IPO_ELASTIC);
- }
-
- if (hold) {
- info->flag |= ACTKEYBLOCK_FLAG_STATIC_HOLD | ACTKEYBLOCK_FLAG_ANY_HOLD;
- }
- }
-
- /* Remember non-bezier interpolation info. */
- if (prev->ipo != BEZT_IPO_BEZ) {
- info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER;
- }
-
- info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn);
+ memset(info, 0, sizeof(ActKeyBlockInfo));
+
+ if (BEZKEYTYPE(beztn) == BEZT_KEYTYPE_MOVEHOLD) {
+ /* Animator tagged a "moving hold"
+ * - Previous key must also be tagged as a moving hold, otherwise
+ * we're just dealing with the first of a pair, and we don't
+ * want to be creating any phantom holds...
+ */
+ if (BEZKEYTYPE(prev) == BEZT_KEYTYPE_MOVEHOLD) {
+ info->flag |= ACTKEYBLOCK_FLAG_MOVING_HOLD | ACTKEYBLOCK_FLAG_ANY_HOLD;
+ }
+ }
+
+ /* Check for same values...
+ * - Handles must have same central value as each other
+ * - Handles which control that section of the curve must be constant
+ */
+ if (IS_EQF(beztn->vec[1][1], prev->vec[1][1])) {
+ bool hold;
+
+ /* Only check handles in case of actual bezier interpolation. */
+ if (prev->ipo == BEZT_IPO_BEZ) {
+ hold = IS_EQF(beztn->vec[1][1], beztn->vec[0][1]) &&
+ IS_EQF(prev->vec[1][1], prev->vec[2][1]);
+ }
+ /* This interpolation type induces movement even between identical keys. */
+ else {
+ hold = !ELEM(prev->ipo, BEZT_IPO_ELASTIC);
+ }
+
+ if (hold) {
+ info->flag |= ACTKEYBLOCK_FLAG_STATIC_HOLD | ACTKEYBLOCK_FLAG_ANY_HOLD;
+ }
+ }
+
+ /* Remember non-bezier interpolation info. */
+ if (prev->ipo != BEZT_IPO_BEZ) {
+ info->flag |= ACTKEYBLOCK_FLAG_NON_BEZIER;
+ }
+
+ info->sel = BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn);
}
static void add_keyblock_info(ActKeyColumn *col, const ActKeyBlockInfo *block)
{
- /* New curve and block. */
- if (col->totcurve <= 1 && col->totblock == 0) {
- memcpy(&col->block, block, sizeof(ActKeyBlockInfo));
- }
- /* Existing curve. */
- else {
- col->block.conflict |= (col->block.flag ^ block->flag);
- col->block.flag |= block->flag;
- col->block.sel |= block->sel;
- }
-
- if (block->flag) {
- col->totblock++;
- }
+ /* New curve and block. */
+ if (col->totcurve <= 1 && col->totblock == 0) {
+ memcpy(&col->block, block, sizeof(ActKeyBlockInfo));
+ }
+ /* Existing curve. */
+ else {
+ col->block.conflict |= (col->block.flag ^ block->flag);
+ col->block.flag |= block->flag;
+ col->block.sel |= block->sel;
+ }
+
+ if (block->flag) {
+ col->totblock++;
+ }
}
static void add_bezt_to_keyblocks_list(DLRBT_Tree *keys, BezTriple *bezt, int bezt_len)
{
- ActKeyColumn *col = keys->first;
-
- if (bezt && bezt_len >= 2) {
- ActKeyBlockInfo block;
-
- /* Find the first key column while inserting dummy blocks. */
- for (; col != NULL && is_cfra_lt(col->cfra, bezt[0].vec[1][0]); col = col->next) {
- add_keyblock_info(col, &dummy_keyblock);
- }
-
- BLI_assert(col != NULL);
-
- /* Insert real blocks. */
- for (int v = 1; col != NULL && v < bezt_len; v++, bezt++) {
- /* Wrong order of bezier keys: resync position. */
- if (is_cfra_lt(bezt[1].vec[1][0], bezt[0].vec[1][0])) {
- /* Backtrack to find the right location. */
- if (is_cfra_lt(bezt[1].vec[1][0], col->cfra)) {
- ActKeyColumn *newcol = (ActKeyColumn *)BLI_dlrbTree_search_exact(
- keys, compare_ak_cfraPtr, &bezt[1].vec[1][0]);
-
- if (newcol != NULL) {
- col = newcol;
-
- /* The previous keyblock is garbage too. */
- if (col->prev != NULL) {
- add_keyblock_info(col->prev, &dummy_keyblock);
- }
- }
- else {
- BLI_assert(false);
- }
- }
-
- continue;
- }
-
- /* Normal sequence */
- BLI_assert(is_cfra_eq(col->cfra, bezt[0].vec[1][0]));
-
- compute_keyblock_data(&block, bezt, bezt + 1);
-
- for (; col != NULL && is_cfra_lt(col->cfra, bezt[1].vec[1][0]); col = col->next) {
- add_keyblock_info(col, &block);
- }
-
- BLI_assert(col != NULL);
- }
- }
-
- /* Insert dummy blocks at the end. */
- for (; col != NULL; col = col->next) {
- add_keyblock_info(col, &dummy_keyblock);
- }
+ ActKeyColumn *col = keys->first;
+
+ if (bezt && bezt_len >= 2) {
+ ActKeyBlockInfo block;
+
+ /* Find the first key column while inserting dummy blocks. */
+ for (; col != NULL && is_cfra_lt(col->cfra, bezt[0].vec[1][0]); col = col->next) {
+ add_keyblock_info(col, &dummy_keyblock);
+ }
+
+ BLI_assert(col != NULL);
+
+ /* Insert real blocks. */
+ for (int v = 1; col != NULL && v < bezt_len; v++, bezt++) {
+ /* Wrong order of bezier keys: resync position. */
+ if (is_cfra_lt(bezt[1].vec[1][0], bezt[0].vec[1][0])) {
+ /* Backtrack to find the right location. */
+ if (is_cfra_lt(bezt[1].vec[1][0], col->cfra)) {
+ ActKeyColumn *newcol = (ActKeyColumn *)BLI_dlrbTree_search_exact(
+ keys, compare_ak_cfraPtr, &bezt[1].vec[1][0]);
+
+ if (newcol != NULL) {
+ col = newcol;
+
+ /* The previous keyblock is garbage too. */
+ if (col->prev != NULL) {
+ add_keyblock_info(col->prev, &dummy_keyblock);
+ }
+ }
+ else {
+ BLI_assert(false);
+ }
+ }
+
+ continue;
+ }
+
+ /* Normal sequence */
+ BLI_assert(is_cfra_eq(col->cfra, bezt[0].vec[1][0]));
+
+ compute_keyblock_data(&block, bezt, bezt + 1);
+
+ for (; col != NULL && is_cfra_lt(col->cfra, bezt[1].vec[1][0]); col = col->next) {
+ add_keyblock_info(col, &block);
+ }
+
+ BLI_assert(col != NULL);
+ }
+ }
+
+ /* Insert dummy blocks at the end. */
+ for (; col != NULL; col = col->next) {
+ add_keyblock_info(col, &dummy_keyblock);
+ }
}
/* Walk through columns and propagate blocks and totcurve.
@@ -478,689 +484,756 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *keys, BezTriple *bezt, int be
*/
static void update_keyblocks(DLRBT_Tree *keys, BezTriple *bezt, int bezt_len)
{
- /* Recompute the prev/next linked list. */
- BLI_dlrbTree_linkedlist_sync(keys);
-
- /* Find the curve count */
- int max_curve = 0;
-
- for (ActKeyColumn *col = keys->first; col; col = col->next) {
- max_curve = MAX2(max_curve, col->totcurve);
- }
-
- /* Propagate blocks to inserted keys */
- ActKeyColumn *prev_ready = NULL;
-
- for (ActKeyColumn *col = keys->first; col; col = col->next) {
- /* Pre-existing column. */
- if (col->totcurve > 0) {
- prev_ready = col;
- }
- /* Newly inserted column, so copy block data from previous. */
- else if (prev_ready != NULL) {
- col->totblock = prev_ready->totblock;
- memcpy(&col->block, &prev_ready->block, sizeof(ActKeyBlockInfo));
- }
-
- col->totcurve = max_curve + 1;
- }
-
- /* Add blocks on top */
- add_bezt_to_keyblocks_list(keys, bezt, bezt_len);
+ /* Recompute the prev/next linked list. */
+ BLI_dlrbTree_linkedlist_sync(keys);
+
+ /* Find the curve count */
+ int max_curve = 0;
+
+ for (ActKeyColumn *col = keys->first; col; col = col->next) {
+ max_curve = MAX2(max_curve, col->totcurve);
+ }
+
+ /* Propagate blocks to inserted keys */
+ ActKeyColumn *prev_ready = NULL;
+
+ for (ActKeyColumn *col = keys->first; col; col = col->next) {
+ /* Pre-existing column. */
+ if (col->totcurve > 0) {
+ prev_ready = col;
+ }
+ /* Newly inserted column, so copy block data from previous. */
+ else if (prev_ready != NULL) {
+ col->totblock = prev_ready->totblock;
+ memcpy(&col->block, &prev_ready->block, sizeof(ActKeyBlockInfo));
+ }
+
+ col->totcurve = max_curve + 1;
+ }
+
+ /* Add blocks on top */
+ add_bezt_to_keyblocks_list(keys, bezt, bezt_len);
}
/* --------- */
bool actkeyblock_is_valid(ActKeyColumn *ac)
{
- return ac != NULL && ac->next != NULL && ac->totblock > 0;
+ return ac != NULL && ac->next != NULL && ac->totblock > 0;
}
/* Checks if ActKeyBlock should exist... */
int actkeyblock_get_valid_hold(ActKeyColumn *ac)
{
- /* check that block is valid */
- if (!actkeyblock_is_valid(ac))
- return 0;
+ /* check that block is valid */
+ if (!actkeyblock_is_valid(ac))
+ return 0;
- const int hold_mask = (ACTKEYBLOCK_FLAG_ANY_HOLD | ACTKEYBLOCK_FLAG_STATIC_HOLD | ACTKEYBLOCK_FLAG_ANY_HOLD);
- return (ac->block.flag & ~ac->block.conflict) & hold_mask;
+ const int hold_mask = (ACTKEYBLOCK_FLAG_ANY_HOLD | ACTKEYBLOCK_FLAG_STATIC_HOLD |
+ ACTKEYBLOCK_FLAG_ANY_HOLD);
+ return (ac->block.flag & ~ac->block.conflict) & hold_mask;
}
/* *************************** Keyframe Drawing *************************** */
-void draw_keyframe_shape(float x, float y, float size, bool sel, short key_type, short mode, float alpha,
- unsigned int pos_id, unsigned int size_id, unsigned int color_id, unsigned int outline_color_id,
- unsigned int flags_id, short handle_type, short extreme_type)
+void draw_keyframe_shape(float x,
+ float y,
+ float size,
+ bool sel,
+ short key_type,
+ short mode,
+ float alpha,
+ unsigned int pos_id,
+ unsigned int size_id,
+ unsigned int color_id,
+ unsigned int outline_color_id,
+ unsigned int flags_id,
+ short handle_type,
+ short extreme_type)
{
- bool draw_fill = ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH);
- bool draw_outline = ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH);
-
- BLI_assert(draw_fill || draw_outline);
-
- /* tweak size of keyframe shape according to type of keyframe
- * - 'proper' keyframes have key_type = 0, so get drawn at full size
- */
- switch (key_type) {
- case BEZT_KEYTYPE_KEYFRAME: /* must be full size */
- break;
-
- case BEZT_KEYTYPE_BREAKDOWN: /* slightly smaller than normal keyframe */
- size *= 0.85f;
- break;
-
- case BEZT_KEYTYPE_MOVEHOLD: /* slightly smaller than normal keyframes
- * (but by less than for breakdowns) */
- size *= 0.925f;
- break;
-
- case BEZT_KEYTYPE_EXTREME: /* slightly larger */
- size *= 1.2f;
- break;
-
- default:
- size -= 0.8f * key_type;
- }
-
- unsigned char fill_col[4];
- unsigned char outline_col[4];
- unsigned int flags = 0;
-
- /* draw! */
- if (draw_fill) {
- /* get interior colors from theme (for selected and unselected only) */
- switch (key_type) {
- case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames (default theme) */
- UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_BREAKDOWN_SELECT : TH_KEYTYPE_BREAKDOWN, fill_col);
- break;
- case BEZT_KEYTYPE_EXTREME: /* reddish frames (default theme) */
- UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_EXTREME_SELECT : TH_KEYTYPE_EXTREME, fill_col);
- break;
- case BEZT_KEYTYPE_JITTER: /* greenish frames (default theme) */
- UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_JITTER_SELECT : TH_KEYTYPE_JITTER, fill_col);
- break;
- case BEZT_KEYTYPE_MOVEHOLD: /* similar to traditional keyframes, but different... */
- UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_MOVEHOLD_SELECT : TH_KEYTYPE_MOVEHOLD, fill_col);
- break;
- case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames (default theme) */
- default:
- UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_KEYFRAME_SELECT : TH_KEYTYPE_KEYFRAME, fill_col);
- }
-
- /* NOTE: we don't use the straight alpha from the theme, or else effects such as
- * graying out protected/muted channels doesn't work correctly!
- */
- fill_col[3] *= alpha;
-
- if (!draw_outline) {
- /* force outline color to match */
- outline_col[0] = fill_col[0];
- outline_col[1] = fill_col[1];
- outline_col[2] = fill_col[2];
- outline_col[3] = fill_col[3];
- }
- }
-
- if (draw_outline) {
- /* exterior - black frame */
- UI_GetThemeColor4ubv(sel ? TH_KEYBORDER_SELECT : TH_KEYBORDER, outline_col);
- outline_col[3] *= alpha;
-
- if (!draw_fill) {
- /* fill color needs to be (outline.rgb, 0) */
- fill_col[0] = outline_col[0];
- fill_col[1] = outline_col[1];
- fill_col[2] = outline_col[2];
- fill_col[3] = 0;
- }
-
- /* Handle type to outline shape. */
- switch (handle_type) {
- case KEYFRAME_HANDLE_AUTO_CLAMP: flags = 0x2; break; /* circle */
- case KEYFRAME_HANDLE_AUTO: flags = 0x12; break; /* circle with dot */
- case KEYFRAME_HANDLE_VECTOR: flags = 0xC; break; /* square */
- case KEYFRAME_HANDLE_ALIGNED: flags = 0x5; break; /* clipped diamond */
-
- case KEYFRAME_HANDLE_FREE:
- default:
- flags = 1; /* diamond */
- }
-
- /* Extreme type to arrow-like shading. */
- if (extreme_type & KEYFRAME_EXTREME_MAX) {
- flags |= 0x100;
- }
- if (extreme_type & KEYFRAME_EXTREME_MIN) {
- flags |= 0x200;
- }
- if (extreme_type & KEYFRAME_EXTREME_MIXED) {
- flags |= 0x400;
- }
- }
-
- immAttr1f(size_id, size);
- immAttr4ubv(color_id, fill_col);
- immAttr4ubv(outline_color_id, outline_col);
- immAttr1u(flags_id, flags);
- immVertex2f(pos_id, x, y);
+ bool draw_fill = ELEM(mode, KEYFRAME_SHAPE_INSIDE, KEYFRAME_SHAPE_BOTH);
+ bool draw_outline = ELEM(mode, KEYFRAME_SHAPE_FRAME, KEYFRAME_SHAPE_BOTH);
+
+ BLI_assert(draw_fill || draw_outline);
+
+ /* tweak size of keyframe shape according to type of keyframe
+ * - 'proper' keyframes have key_type = 0, so get drawn at full size
+ */
+ switch (key_type) {
+ case BEZT_KEYTYPE_KEYFRAME: /* must be full size */
+ break;
+
+ case BEZT_KEYTYPE_BREAKDOWN: /* slightly smaller than normal keyframe */
+ size *= 0.85f;
+ break;
+
+ case BEZT_KEYTYPE_MOVEHOLD: /* slightly smaller than normal keyframes
+ * (but by less than for breakdowns) */
+ size *= 0.925f;
+ break;
+
+ case BEZT_KEYTYPE_EXTREME: /* slightly larger */
+ size *= 1.2f;
+ break;
+
+ default:
+ size -= 0.8f * key_type;
+ }
+
+ unsigned char fill_col[4];
+ unsigned char outline_col[4];
+ unsigned int flags = 0;
+
+ /* draw! */
+ if (draw_fill) {
+ /* get interior colors from theme (for selected and unselected only) */
+ switch (key_type) {
+ case BEZT_KEYTYPE_BREAKDOWN: /* bluish frames (default theme) */
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_BREAKDOWN_SELECT : TH_KEYTYPE_BREAKDOWN, fill_col);
+ break;
+ case BEZT_KEYTYPE_EXTREME: /* reddish frames (default theme) */
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_EXTREME_SELECT : TH_KEYTYPE_EXTREME, fill_col);
+ break;
+ case BEZT_KEYTYPE_JITTER: /* greenish frames (default theme) */
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_JITTER_SELECT : TH_KEYTYPE_JITTER, fill_col);
+ break;
+ case BEZT_KEYTYPE_MOVEHOLD: /* similar to traditional keyframes, but different... */
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_MOVEHOLD_SELECT : TH_KEYTYPE_MOVEHOLD, fill_col);
+ break;
+ case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames (default theme) */
+ default:
+ UI_GetThemeColor4ubv(sel ? TH_KEYTYPE_KEYFRAME_SELECT : TH_KEYTYPE_KEYFRAME, fill_col);
+ }
+
+ /* NOTE: we don't use the straight alpha from the theme, or else effects such as
+ * graying out protected/muted channels doesn't work correctly!
+ */
+ fill_col[3] *= alpha;
+
+ if (!draw_outline) {
+ /* force outline color to match */
+ outline_col[0] = fill_col[0];
+ outline_col[1] = fill_col[1];
+ outline_col[2] = fill_col[2];
+ outline_col[3] = fill_col[3];
+ }
+ }
+
+ if (draw_outline) {
+ /* exterior - black frame */
+ UI_GetThemeColor4ubv(sel ? TH_KEYBORDER_SELECT : TH_KEYBORDER, outline_col);
+ outline_col[3] *= alpha;
+
+ if (!draw_fill) {
+ /* fill color needs to be (outline.rgb, 0) */
+ fill_col[0] = outline_col[0];
+ fill_col[1] = outline_col[1];
+ fill_col[2] = outline_col[2];
+ fill_col[3] = 0;
+ }
+
+ /* Handle type to outline shape. */
+ switch (handle_type) {
+ case KEYFRAME_HANDLE_AUTO_CLAMP:
+ flags = 0x2;
+ break; /* circle */
+ case KEYFRAME_HANDLE_AUTO:
+ flags = 0x12;
+ break; /* circle with dot */
+ case KEYFRAME_HANDLE_VECTOR:
+ flags = 0xC;
+ break; /* square */
+ case KEYFRAME_HANDLE_ALIGNED:
+ flags = 0x5;
+ break; /* clipped diamond */
+
+ case KEYFRAME_HANDLE_FREE:
+ default:
+ flags = 1; /* diamond */
+ }
+
+ /* Extreme type to arrow-like shading. */
+ if (extreme_type & KEYFRAME_EXTREME_MAX) {
+ flags |= 0x100;
+ }
+ if (extreme_type & KEYFRAME_EXTREME_MIN) {
+ flags |= 0x200;
+ }
+ if (extreme_type & KEYFRAME_EXTREME_MIXED) {
+ flags |= 0x400;
+ }
+ }
+
+ immAttr1f(size_id, size);
+ immAttr4ubv(color_id, fill_col);
+ immAttr4ubv(outline_color_id, outline_col);
+ immAttr1u(flags_id, flags);
+ immVertex2f(pos_id, x, y);
}
-static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, float ypos, float yscale_fac, bool channelLocked, int saction_flag)
+static void draw_keylist(View2D *v2d,
+ DLRBT_Tree *keys,
+ float ypos,
+ float yscale_fac,
+ bool channelLocked,
+ int saction_flag)
{
- const float icon_sz = U.widget_unit * 0.5f * yscale_fac;
- const float half_icon_sz = 0.5f * icon_sz;
- const float smaller_sz = 0.35f * icon_sz;
- const float ipo_sz = 0.1f * icon_sz;
-
- GPU_blend(true);
-
- /* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */
- /* TODO: allow this opacity factor to be themed? */
- float alpha = channelLocked ? 0.25f : 1.0f;
-
- /* Show interpolation and handle type? */
- bool show_ipo = (saction_flag & SACTION_SHOW_INTERPOLATION) != 0;
-
- /* draw keyblocks */
- if (keys) {
- float sel_color[4], unsel_color[4];
- float sel_mhcol[4], unsel_mhcol[4];
- float ipo_color[4], ipo_color_mix[4];
-
- /* cache colours first */
- UI_GetThemeColor4fv(TH_STRIP_SELECT, sel_color);
- UI_GetThemeColor4fv(TH_STRIP, unsel_color);
- UI_GetThemeColor4fv(TH_DOPESHEET_IPOLINE, ipo_color);
-
- sel_color[3] *= alpha;
- unsel_color[3] *= alpha;
- ipo_color[3] *= alpha;
-
- copy_v4_v4(sel_mhcol, sel_color);
- sel_mhcol[3] *= 0.8f;
- copy_v4_v4(unsel_mhcol, unsel_color);
- unsel_mhcol[3] *= 0.8f;
- copy_v4_v4(ipo_color_mix, ipo_color);
- ipo_color_mix[3] *= 0.5f;
-
- uint block_len = 0;
- for (ActKeyColumn *ab = keys->first; ab; ab = ab->next) {
- if (actkeyblock_get_valid_hold(ab)) {
- block_len++;
- }
- if (show_ipo && actkeyblock_is_valid(ab) && (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) {
- block_len++;
- }
- }
-
- if (block_len > 0) {
- GPUVertFormat *format = immVertexFormat();
- uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
- immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
-
- immBegin(GPU_PRIM_TRIS, 6 * block_len);
- for (ActKeyColumn *ab = keys->first; ab; ab = ab->next) {
- int valid_hold = actkeyblock_get_valid_hold(ab);
- if (valid_hold != 0) {
- if ((valid_hold & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) {
- /* draw "moving hold" long-keyframe block - slightly smaller */
- immRectf_fast_with_color(pos_id, color_id,
- ab->cfra, ypos - smaller_sz, ab->next->cfra, ypos + smaller_sz,
- (ab->block.sel) ? sel_mhcol : unsel_mhcol);
- }
- else {
- /* draw standard long-keyframe block */
- immRectf_fast_with_color(pos_id, color_id,
- ab->cfra, ypos - half_icon_sz, ab->next->cfra, ypos + half_icon_sz,
- (ab->block.sel) ? sel_color : unsel_color);
- }
- }
- if (show_ipo && actkeyblock_is_valid(ab) && (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) {
- /* draw an interpolation line */
- immRectf_fast_with_color(pos_id, color_id,
- ab->cfra, ypos - ipo_sz, ab->next->cfra, ypos + ipo_sz,
- (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ipo_color_mix : ipo_color);
- }
- }
- immEnd();
- immUnbindProgram();
- }
- }
-
- if (keys) {
- /* count keys */
- uint key_len = 0;
- for (ActKeyColumn *ak = keys->first; ak; ak = ak->next) {
- /* optimization: if keyframe doesn't appear within 5 units (screenspace) in visible area, don't draw
- * - this might give some improvements, since we current have to flip between view/region matrices
- */
- if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax))
- key_len++;
- }
-
- if (key_len > 0) {
- /* draw keys */
- GPUVertFormat *format = immVertexFormat();
- uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
- uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
- uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
- uint outline_color_id = GPU_vertformat_attr_add(format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
- uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT);
- immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
- GPU_enable_program_point_size();
- immUniform2f("ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1);
- immBegin(GPU_PRIM_POINTS, key_len);
-
- short handle_type = KEYFRAME_HANDLE_NONE, extreme_type = KEYFRAME_EXTREME_NONE;
-
- for (ActKeyColumn *ak = keys->first; ak; ak = ak->next) {
- if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax)) {
- if (show_ipo) {
- handle_type = ak->handle_type;
- }
- if (saction_flag & SACTION_SHOW_EXTREMES) {
- extreme_type = ak->extreme_type;
- }
-
- draw_keyframe_shape(ak->cfra, ypos, icon_sz, (ak->sel & SELECT), ak->key_type, KEYFRAME_SHAPE_BOTH, alpha,
- pos_id, size_id, color_id, outline_color_id, flags_id, handle_type, extreme_type);
- }
- }
-
- immEnd();
- GPU_disable_program_point_size();
- immUnbindProgram();
- }
- }
-
- GPU_blend(false);
+ const float icon_sz = U.widget_unit * 0.5f * yscale_fac;
+ const float half_icon_sz = 0.5f * icon_sz;
+ const float smaller_sz = 0.35f * icon_sz;
+ const float ipo_sz = 0.1f * icon_sz;
+
+ GPU_blend(true);
+
+ /* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */
+ /* TODO: allow this opacity factor to be themed? */
+ float alpha = channelLocked ? 0.25f : 1.0f;
+
+ /* Show interpolation and handle type? */
+ bool show_ipo = (saction_flag & SACTION_SHOW_INTERPOLATION) != 0;
+
+ /* draw keyblocks */
+ if (keys) {
+ float sel_color[4], unsel_color[4];
+ float sel_mhcol[4], unsel_mhcol[4];
+ float ipo_color[4], ipo_color_mix[4];
+
+ /* cache colours first */
+ UI_GetThemeColor4fv(TH_STRIP_SELECT, sel_color);
+ UI_GetThemeColor4fv(TH_STRIP, unsel_color);
+ UI_GetThemeColor4fv(TH_DOPESHEET_IPOLINE, ipo_color);
+
+ sel_color[3] *= alpha;
+ unsel_color[3] *= alpha;
+ ipo_color[3] *= alpha;
+
+ copy_v4_v4(sel_mhcol, sel_color);
+ sel_mhcol[3] *= 0.8f;
+ copy_v4_v4(unsel_mhcol, unsel_color);
+ unsel_mhcol[3] *= 0.8f;
+ copy_v4_v4(ipo_color_mix, ipo_color);
+ ipo_color_mix[3] *= 0.5f;
+
+ uint block_len = 0;
+ for (ActKeyColumn *ab = keys->first; ab; ab = ab->next) {
+ if (actkeyblock_get_valid_hold(ab)) {
+ block_len++;
+ }
+ if (show_ipo && actkeyblock_is_valid(ab) && (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) {
+ block_len++;
+ }
+ }
+
+ if (block_len > 0) {
+ GPUVertFormat *format = immVertexFormat();
+ uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint color_id = GPU_vertformat_attr_add(format, "color", GPU_COMP_F32, 4, GPU_FETCH_FLOAT);
+ immBindBuiltinProgram(GPU_SHADER_2D_FLAT_COLOR);
+
+ immBegin(GPU_PRIM_TRIS, 6 * block_len);
+ for (ActKeyColumn *ab = keys->first; ab; ab = ab->next) {
+ int valid_hold = actkeyblock_get_valid_hold(ab);
+ if (valid_hold != 0) {
+ if ((valid_hold & ACTKEYBLOCK_FLAG_STATIC_HOLD) == 0) {
+ /* draw "moving hold" long-keyframe block - slightly smaller */
+ immRectf_fast_with_color(pos_id,
+ color_id,
+ ab->cfra,
+ ypos - smaller_sz,
+ ab->next->cfra,
+ ypos + smaller_sz,
+ (ab->block.sel) ? sel_mhcol : unsel_mhcol);
+ }
+ else {
+ /* draw standard long-keyframe block */
+ immRectf_fast_with_color(pos_id,
+ color_id,
+ ab->cfra,
+ ypos - half_icon_sz,
+ ab->next->cfra,
+ ypos + half_icon_sz,
+ (ab->block.sel) ? sel_color : unsel_color);
+ }
+ }
+ if (show_ipo && actkeyblock_is_valid(ab) &&
+ (ab->block.flag & ACTKEYBLOCK_FLAG_NON_BEZIER)) {
+ /* draw an interpolation line */
+ immRectf_fast_with_color(
+ pos_id,
+ color_id,
+ ab->cfra,
+ ypos - ipo_sz,
+ ab->next->cfra,
+ ypos + ipo_sz,
+ (ab->block.conflict & ACTKEYBLOCK_FLAG_NON_BEZIER) ? ipo_color_mix : ipo_color);
+ }
+ }
+ immEnd();
+ immUnbindProgram();
+ }
+ }
+
+ if (keys) {
+ /* count keys */
+ uint key_len = 0;
+ for (ActKeyColumn *ak = keys->first; ak; ak = ak->next) {
+ /* optimization: if keyframe doesn't appear within 5 units (screenspace) in visible area, don't draw
+ * - this might give some improvements, since we current have to flip between view/region matrices
+ */
+ if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax))
+ key_len++;
+ }
+
+ if (key_len > 0) {
+ /* draw keys */
+ GPUVertFormat *format = immVertexFormat();
+ uint pos_id = GPU_vertformat_attr_add(format, "pos", GPU_COMP_F32, 2, GPU_FETCH_FLOAT);
+ uint size_id = GPU_vertformat_attr_add(format, "size", GPU_COMP_F32, 1, GPU_FETCH_FLOAT);
+ uint color_id = GPU_vertformat_attr_add(
+ format, "color", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ uint outline_color_id = GPU_vertformat_attr_add(
+ format, "outlineColor", GPU_COMP_U8, 4, GPU_FETCH_INT_TO_FLOAT_UNIT);
+ uint flags_id = GPU_vertformat_attr_add(format, "flags", GPU_COMP_U32, 1, GPU_FETCH_INT);
+ immBindBuiltinProgram(GPU_SHADER_KEYFRAME_DIAMOND);
+ GPU_enable_program_point_size();
+ immUniform2f(
+ "ViewportSize", BLI_rcti_size_x(&v2d->mask) + 1, BLI_rcti_size_y(&v2d->mask) + 1);
+ immBegin(GPU_PRIM_POINTS, key_len);
+
+ short handle_type = KEYFRAME_HANDLE_NONE, extreme_type = KEYFRAME_EXTREME_NONE;
+
+ for (ActKeyColumn *ak = keys->first; ak; ak = ak->next) {
+ if (IN_RANGE_INCL(ak->cfra, v2d->cur.xmin, v2d->cur.xmax)) {
+ if (show_ipo) {
+ handle_type = ak->handle_type;
+ }
+ if (saction_flag & SACTION_SHOW_EXTREMES) {
+ extreme_type = ak->extreme_type;
+ }
+
+ draw_keyframe_shape(ak->cfra,
+ ypos,
+ icon_sz,
+ (ak->sel & SELECT),
+ ak->key_type,
+ KEYFRAME_SHAPE_BOTH,
+ alpha,
+ pos_id,
+ size_id,
+ color_id,
+ outline_color_id,
+ flags_id,
+ handle_type,
+ extreme_type);
+ }
+ }
+
+ immEnd();
+ GPU_disable_program_point_size();
+ immUnbindProgram();
+ }
+ }
+
+ GPU_blend(false);
}
/* *************************** Channel Drawing Funcs *************************** */
-void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos, float yscale_fac, int saction_flag)
+void draw_summary_channel(
+ View2D *v2d, bAnimContext *ac, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- saction_flag &= ~SACTION_SHOW_EXTREMES;
+ saction_flag &= ~SACTION_SHOW_EXTREMES;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- summary_to_keylist(ac, &keys, saction_flag);
+ summary_to_keylist(ac, &keys, saction_flag);
- draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos, float yscale_fac, int saction_flag)
+void draw_scene_channel(
+ View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- saction_flag &= ~SACTION_SHOW_EXTREMES;
+ saction_flag &= ~SACTION_SHOW_EXTREMES;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- scene_to_keylist(ads, sce, &keys, saction_flag);
+ scene_to_keylist(ads, sce, &keys, saction_flag);
- draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos, float yscale_fac, int saction_flag)
+void draw_object_channel(
+ View2D *v2d, bDopeSheet *ads, Object *ob, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- saction_flag &= ~SACTION_SHOW_EXTREMES;
+ saction_flag &= ~SACTION_SHOW_EXTREMES;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- ob_to_keylist(ads, ob, &keys, saction_flag);
+ ob_to_keylist(ads, ob, &keys, saction_flag);
- draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, float yscale_fac, int saction_flag)
+void draw_fcurve_channel(
+ View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- bool locked = (fcu->flag & FCURVE_PROTECTED) ||
- ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
- ((adt && adt->action) && ID_IS_LINKED(adt->action));
+ bool locked = (fcu->flag & FCURVE_PROTECTED) ||
+ ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ||
+ ((adt && adt->action) && ID_IS_LINKED(adt->action));
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- fcurve_to_keylist(adt, fcu, &keys, saction_flag);
+ fcurve_to_keylist(adt, fcu, &keys, saction_flag);
- draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos, float yscale_fac, int saction_flag)
+void draw_agroup_channel(
+ View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- bool locked = (agrp->flag & AGRP_PROTECTED) ||
- ((adt && adt->action) && ID_IS_LINKED(adt->action));
+ bool locked = (agrp->flag & AGRP_PROTECTED) ||
+ ((adt && adt->action) && ID_IS_LINKED(adt->action));
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- agroup_to_keylist(adt, agrp, &keys, saction_flag);
+ agroup_to_keylist(adt, agrp, &keys, saction_flag);
- draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos, float yscale_fac, int saction_flag)
+void draw_action_channel(
+ View2D *v2d, AnimData *adt, bAction *act, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- bool locked = (act && ID_IS_LINKED(act));
+ bool locked = (act && ID_IS_LINKED(act));
- saction_flag &= ~SACTION_SHOW_EXTREMES;
+ saction_flag &= ~SACTION_SHOW_EXTREMES;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- action_to_keylist(adt, act, &keys, saction_flag);
+ action_to_keylist(adt, act, &keys, saction_flag);
- draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos, float yscale_fac, int saction_flag)
+void draw_gpencil_channel(
+ View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- saction_flag &= ~SACTION_SHOW_EXTREMES;
+ saction_flag &= ~SACTION_SHOW_EXTREMES;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- gpencil_to_keylist(ads, gpd, &keys, false);
+ gpencil_to_keylist(ads, gpd, &keys, false);
- draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, false, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos, float yscale_fac, int saction_flag)
+void draw_gpl_channel(
+ View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos, float yscale_fac, int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- bool locked = (gpl->flag & GP_LAYER_LOCKED) != 0;
+ bool locked = (gpl->flag & GP_LAYER_LOCKED) != 0;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- gpl_to_keylist(ads, gpl, &keys);
+ gpl_to_keylist(ads, gpl, &keys);
- draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
-void draw_masklay_channel(View2D *v2d, bDopeSheet *ads, MaskLayer *masklay, float ypos, float yscale_fac, int saction_flag)
+void draw_masklay_channel(View2D *v2d,
+ bDopeSheet *ads,
+ MaskLayer *masklay,
+ float ypos,
+ float yscale_fac,
+ int saction_flag)
{
- DLRBT_Tree keys;
+ DLRBT_Tree keys;
- bool locked = (masklay->flag & MASK_LAYERFLAG_LOCKED) != 0;
+ bool locked = (masklay->flag & MASK_LAYERFLAG_LOCKED) != 0;
- BLI_dlrbTree_init(&keys);
+ BLI_dlrbTree_init(&keys);
- mask_to_keylist(ads, masklay, &keys);
+ mask_to_keylist(ads, masklay, &keys);
- draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
+ draw_keylist(v2d, &keys, ypos, yscale_fac, locked, saction_flag);
- BLI_dlrbTree_free(&keys);
+ BLI_dlrbTree_free(&keys);
}
/* *************************** Keyframe List Conversions *************************** */
void summary_to_keylist(bAnimContext *ac, DLRBT_Tree *keys, int saction_flag)
{
- if (ac) {
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
-
- /* get F-Curves to take keyframes from */
- filter = ANIMFILTER_DATA_VISIBLE;
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through each F-Curve, grabbing the keyframes */
- for (ale = anim_data.first; ale; ale = ale->next) {
- /* Why not use all #eAnim_KeyType here?
- * All of the other key types are actually "summaries" themselves,
- * and will just end up duplicating stuff that comes up through
- * standard filtering of just F-Curves. Given the way that these work,
- * there isn't really any benefit at all from including them. - Aligorith */
-
- switch (ale->datatype) {
- case ALE_FCURVE:
- fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
- break;
- case ALE_MASKLAY:
- mask_to_keylist(ac->ads, ale->data, keys);
- break;
- case ALE_GPFRAME:
- gpl_to_keylist(ac->ads, ale->data, keys);
- break;
- default:
- // printf("%s: datatype %d unhandled\n", __func__, ale->datatype);
- break;
- }
- }
-
- ANIM_animdata_freelist(&anim_data);
- }
+ if (ac) {
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ /* get F-Curves to take keyframes from */
+ filter = ANIMFILTER_DATA_VISIBLE;
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through each F-Curve, grabbing the keyframes */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ /* Why not use all #eAnim_KeyType here?
+ * All of the other key types are actually "summaries" themselves,
+ * and will just end up duplicating stuff that comes up through
+ * standard filtering of just F-Curves. Given the way that these work,
+ * there isn't really any benefit at all from including them. - Aligorith */
+
+ switch (ale->datatype) {
+ case ALE_FCURVE:
+ fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
+ break;
+ case ALE_MASKLAY:
+ mask_to_keylist(ac->ads, ale->data, keys);
+ break;
+ case ALE_GPFRAME:
+ gpl_to_keylist(ac->ads, ale->data, keys);
+ break;
+ default:
+ // printf("%s: datatype %d unhandled\n", __func__, ale->datatype);
+ break;
+ }
+ }
+
+ ANIM_animdata_freelist(&anim_data);
+ }
}
void scene_to_keylist(bDopeSheet *ads, Scene *sce, DLRBT_Tree *keys, int saction_flag)
{
- bAnimContext ac = {NULL};
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ bAnimContext ac = {NULL};
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- bAnimListElem dummychan = {NULL};
+ bAnimListElem dummychan = {NULL};
- if (sce == NULL)
- return;
+ if (sce == NULL)
+ return;
- /* create a dummy wrapper data to work with */
- dummychan.type = ANIMTYPE_SCENE;
- dummychan.data = sce;
- dummychan.id = &sce->id;
- dummychan.adt = sce->adt;
+ /* create a dummy wrapper data to work with */
+ dummychan.type = ANIMTYPE_SCENE;
+ dummychan.data = sce;
+ dummychan.id = &sce->id;
+ dummychan.adt = sce->adt;
- ac.ads = ads;
- ac.data = &dummychan;
- ac.datatype = ANIMCONT_CHANNEL;
+ ac.ads = ads;
+ ac.data = &dummychan;
+ ac.datatype = ANIMCONT_CHANNEL;
- /* get F-Curves to take keyframes from */
- filter = ANIMFILTER_DATA_VISIBLE; // curves only
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* get F-Curves to take keyframes from */
+ filter = ANIMFILTER_DATA_VISIBLE; // curves only
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- /* loop through each F-Curve, grabbing the keyframes */
- for (ale = anim_data.first; ale; ale = ale->next)
- fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
+ /* loop through each F-Curve, grabbing the keyframes */
+ for (ale = anim_data.first; ale; ale = ale->next)
+ fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
void ob_to_keylist(bDopeSheet *ads, Object *ob, DLRBT_Tree *keys, int saction_flag)
{
- bAnimContext ac = {NULL};
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ bAnimContext ac = {NULL};
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- bAnimListElem dummychan = {NULL};
- Base dummybase = {NULL};
+ bAnimListElem dummychan = {NULL};
+ Base dummybase = {NULL};
- if (ob == NULL)
- return;
+ if (ob == NULL)
+ return;
- /* create a dummy wrapper data to work with */
- dummybase.object = ob;
+ /* create a dummy wrapper data to work with */
+ dummybase.object = ob;
- dummychan.type = ANIMTYPE_OBJECT;
- dummychan.data = &dummybase;
- dummychan.id = &ob->id;
- dummychan.adt = ob->adt;
+ dummychan.type = ANIMTYPE_OBJECT;
+ dummychan.data = &dummybase;
+ dummychan.id = &ob->id;
+ dummychan.adt = ob->adt;
- ac.ads = ads;
- ac.data = &dummychan;
- ac.datatype = ANIMCONT_CHANNEL;
+ ac.ads = ads;
+ ac.data = &dummychan;
+ ac.datatype = ANIMCONT_CHANNEL;
- /* get F-Curves to take keyframes from */
- filter = ANIMFILTER_DATA_VISIBLE; // curves only
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* get F-Curves to take keyframes from */
+ filter = ANIMFILTER_DATA_VISIBLE; // curves only
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- /* loop through each F-Curve, grabbing the keyframes */
- for (ale = anim_data.first; ale; ale = ale->next)
- fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
+ /* loop through each F-Curve, grabbing the keyframes */
+ for (ale = anim_data.first; ale; ale = ale->next)
+ fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
-void cachefile_to_keylist(bDopeSheet *ads, CacheFile *cache_file, DLRBT_Tree *keys, int saction_flag)
+void cachefile_to_keylist(bDopeSheet *ads,
+ CacheFile *cache_file,
+ DLRBT_Tree *keys,
+ int saction_flag)
{
- if (cache_file == NULL) {
- return;
- }
-
- /* create a dummy wrapper data to work with */
- bAnimListElem dummychan = {NULL};
- dummychan.type = ANIMTYPE_DSCACHEFILE;
- dummychan.data = cache_file;
- dummychan.id = &cache_file->id;
- dummychan.adt = cache_file->adt;
-
- bAnimContext ac = {NULL};
- ac.ads = ads;
- ac.data = &dummychan;
- ac.datatype = ANIMCONT_CHANNEL;
-
- /* get F-Curves to take keyframes from */
- ListBase anim_data = { NULL, NULL };
- int filter = ANIMFILTER_DATA_VISIBLE; // curves only
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
-
- /* loop through each F-Curve, grabbing the keyframes */
- for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next) {
- fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
- }
-
- ANIM_animdata_freelist(&anim_data);
+ if (cache_file == NULL) {
+ return;
+ }
+
+ /* create a dummy wrapper data to work with */
+ bAnimListElem dummychan = {NULL};
+ dummychan.type = ANIMTYPE_DSCACHEFILE;
+ dummychan.data = cache_file;
+ dummychan.id = &cache_file->id;
+ dummychan.adt = cache_file->adt;
+
+ bAnimContext ac = {NULL};
+ ac.ads = ads;
+ ac.data = &dummychan;
+ ac.datatype = ANIMCONT_CHANNEL;
+
+ /* get F-Curves to take keyframes from */
+ ListBase anim_data = {NULL, NULL};
+ int filter = ANIMFILTER_DATA_VISIBLE; // curves only
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+
+ /* loop through each F-Curve, grabbing the keyframes */
+ for (bAnimListElem *ale = anim_data.first; ale; ale = ale->next) {
+ fcurve_to_keylist(ale->adt, ale->data, keys, saction_flag);
+ }
+
+ ANIM_animdata_freelist(&anim_data);
}
void fcurve_to_keylist(AnimData *adt, FCurve *fcu, DLRBT_Tree *keys, int saction_flag)
{
- if (fcu && fcu->totvert && fcu->bezt) {
- /* apply NLA-mapping (if applicable) */
- if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0);
+ if (fcu && fcu->totvert && fcu->bezt) {
+ /* apply NLA-mapping (if applicable) */
+ if (adt)
+ ANIM_nla_mapping_apply_fcurve(adt, fcu, 0, 0);
- /* Check if the curve is cyclic. */
- bool is_cyclic = BKE_fcurve_is_cyclic(fcu) && (fcu->totvert >= 2);
- bool do_extremes = (saction_flag & SACTION_SHOW_EXTREMES) != 0;
+ /* Check if the curve is cyclic. */
+ bool is_cyclic = BKE_fcurve_is_cyclic(fcu) && (fcu->totvert >= 2);
+ bool do_extremes = (saction_flag & SACTION_SHOW_EXTREMES) != 0;
- /* loop through beztriples, making ActKeysColumns */
- BezTripleChain chain = { 0 };
+ /* loop through beztriples, making ActKeysColumns */
+ BezTripleChain chain = {0};
- for (int v = 0; v < fcu->totvert; v++) {
- chain.cur = &fcu->bezt[v];
+ for (int v = 0; v < fcu->totvert; v++) {
+ chain.cur = &fcu->bezt[v];
- /* Neighbor keys, accounting for being cyclic. */
- if (do_extremes) {
- chain.prev = (v > 0) ? &fcu->bezt[v - 1] : is_cyclic ? &fcu->bezt[fcu->totvert - 2] : NULL;
- chain.next = (v + 1 < fcu->totvert) ? &fcu->bezt[v + 1] : is_cyclic ? &fcu->bezt[1] : NULL;
- }
+ /* Neighbor keys, accounting for being cyclic. */
+ if (do_extremes) {
+ chain.prev = (v > 0) ? &fcu->bezt[v - 1] : is_cyclic ? &fcu->bezt[fcu->totvert - 2] : NULL;
+ chain.next = (v + 1 < fcu->totvert) ? &fcu->bezt[v + 1] : is_cyclic ? &fcu->bezt[1] : NULL;
+ }
- add_bezt_to_keycolumns_list(keys, &chain);
- }
+ add_bezt_to_keycolumns_list(keys, &chain);
+ }
- /* Update keyblocks. */
- update_keyblocks(keys, fcu->bezt, fcu->totvert);
+ /* Update keyblocks. */
+ update_keyblocks(keys, fcu->bezt, fcu->totvert);
- /* unapply NLA-mapping if applicable */
- if (adt)
- ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0);
- }
+ /* unapply NLA-mapping if applicable */
+ if (adt)
+ ANIM_nla_mapping_apply_fcurve(adt, fcu, 1, 0);
+ }
}
void agroup_to_keylist(AnimData *adt, bActionGroup *agrp, DLRBT_Tree *keys, int saction_flag)
{
- FCurve *fcu;
-
- if (agrp) {
- /* loop through F-Curves */
- for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next) {
- fcurve_to_keylist(adt, fcu, keys, saction_flag);
- }
- }
+ FCurve *fcu;
+
+ if (agrp) {
+ /* loop through F-Curves */
+ for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next) {
+ fcurve_to_keylist(adt, fcu, keys, saction_flag);
+ }
+ }
}
void action_to_keylist(AnimData *adt, bAction *act, DLRBT_Tree *keys, int saction_flag)
{
- FCurve *fcu;
-
- if (act) {
- /* loop through F-Curves */
- for (fcu = act->curves.first; fcu; fcu = fcu->next) {
- fcurve_to_keylist(adt, fcu, keys, saction_flag);
- }
- }
+ FCurve *fcu;
+
+ if (act) {
+ /* loop through F-Curves */
+ for (fcu = act->curves.first; fcu; fcu = fcu->next) {
+ fcurve_to_keylist(adt, fcu, keys, saction_flag);
+ }
+ }
}
-
void gpencil_to_keylist(bDopeSheet *ads, bGPdata *gpd, DLRBT_Tree *keys, const bool active)
{
- bGPDlayer *gpl;
-
- if (gpd && keys) {
- /* for now, just aggregate out all the frames, but only for visible layers */
- for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) {
- if ((gpl->flag & GP_LAYER_HIDE) == 0) {
- if ((!active) || ((active) && (gpl->flag & GP_LAYER_SELECT))) {
- gpl_to_keylist(ads, gpl, keys);
- }
- }
- }
- }
+ bGPDlayer *gpl;
+
+ if (gpd && keys) {
+ /* for now, just aggregate out all the frames, but only for visible layers */
+ for (gpl = gpd->layers.last; gpl; gpl = gpl->prev) {
+ if ((gpl->flag & GP_LAYER_HIDE) == 0) {
+ if ((!active) || ((active) && (gpl->flag & GP_LAYER_SELECT))) {
+ gpl_to_keylist(ads, gpl, keys);
+ }
+ }
+ }
+ }
}
void gpl_to_keylist(bDopeSheet *UNUSED(ads), bGPDlayer *gpl, DLRBT_Tree *keys)
{
- bGPDframe *gpf;
+ bGPDframe *gpf;
- if (gpl && keys) {
- /* although the frames should already be in an ordered list, they are not suitable for displaying yet */
- for (gpf = gpl->frames.first; gpf; gpf = gpf->next)
- add_gpframe_to_keycolumns_list(keys, gpf);
+ if (gpl && keys) {
+ /* although the frames should already be in an ordered list, they are not suitable for displaying yet */
+ for (gpf = gpl->frames.first; gpf; gpf = gpf->next)
+ add_gpframe_to_keycolumns_list(keys, gpf);
- update_keyblocks(keys, NULL, 0);
- }
+ update_keyblocks(keys, NULL, 0);
+ }
}
void mask_to_keylist(bDopeSheet *UNUSED(ads), MaskLayer *masklay, DLRBT_Tree *keys)
{
- MaskLayerShape *masklay_shape;
-
- if (masklay && keys) {
- for (masklay_shape = masklay->splines_shapes.first;
- masklay_shape;
- masklay_shape = masklay_shape->next)
- {
- add_masklay_to_keycolumns_list(keys, masklay_shape);
- }
-
- update_keyblocks(keys, NULL, 0);
- }
+ MaskLayerShape *masklay_shape;
+
+ if (masklay && keys) {
+ for (masklay_shape = masklay->splines_shapes.first; masklay_shape;
+ masklay_shape = masklay_shape->next) {
+ add_masklay_to_keycolumns_list(keys, masklay_shape);
+ }
+
+ update_keyblocks(keys, NULL, 0);
+ }
}
diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c
index 837a25946da..bb0ab112af4 100644
--- a/source/blender/editors/animation/keyframes_edit.c
+++ b/source/blender/editors/animation/keyframes_edit.c
@@ -20,7 +20,6 @@
* \ingroup edanimation
*/
-
#include <stdlib.h>
#include <string.h>
#include <math.h>
@@ -71,329 +70,369 @@
* operation on them, and optionally applies an F-Curve validation function afterwards.
*/
// TODO: make this function work on samples too...
-short ANIM_fcurve_keyframes_loop(KeyframeEditData *ked, FCurve *fcu, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
-{
- BezTriple *bezt;
- short ok = 0;
- unsigned int i;
-
- /* sanity check */
- if (ELEM(NULL, fcu, fcu->bezt))
- return 0;
-
- /* set the F-Curve into the editdata so that it can be accessed */
- if (ked) {
- ked->fcu = fcu;
- ked->curIndex = 0;
- ked->curflags = ok;
- }
-
- /* if function to apply to bezier curves is set, then loop through executing it on beztriples */
- if (key_cb) {
- /* if there's a validation func, include that check in the loop
- * (this is should be more efficient than checking for it in every loop)
- */
- if (key_ok) {
- for (bezt = fcu->bezt, i = 0; i < fcu->totvert; bezt++, i++) {
- if (ked) {
- /* advance the index, and reset the ok flags (to not influence the result) */
- ked->curIndex = i;
- ked->curflags = 0;
- }
-
- /* Only operate on this BezTriple if it fulfills the criteria of the validation func */
- if ((ok = key_ok(ked, bezt))) {
- if (ked) ked->curflags = ok;
-
- /* Exit with return-code '1' if function returns positive
- * This is useful if finding if some BezTriple satisfies a condition.
- */
- if (key_cb(ked, bezt)) return 1;
- }
- }
- }
- else {
- for (bezt = fcu->bezt, i = 0; i < fcu->totvert; bezt++, i++) {
- if (ked) ked->curIndex = i;
-
- /* Exit with return-code '1' if function returns positive
- * This is useful if finding if some BezTriple satisfies a condition.
- */
- if (key_cb(ked, bezt)) return 1;
- }
- }
- }
-
- /* unset the F-Curve from the editdata now that it's done */
- if (ked) {
- ked->fcu = NULL;
- ked->curIndex = 0;
- ked->curflags = 0;
- }
-
- /* if fcu_cb (F-Curve post-editing callback) has been specified then execute it */
- if (fcu_cb)
- fcu_cb(fcu);
-
- /* done */
- return 0;
+short ANIM_fcurve_keyframes_loop(KeyframeEditData *ked,
+ FCurve *fcu,
+ KeyframeEditFunc key_ok,
+ KeyframeEditFunc key_cb,
+ FcuEditFunc fcu_cb)
+{
+ BezTriple *bezt;
+ short ok = 0;
+ unsigned int i;
+
+ /* sanity check */
+ if (ELEM(NULL, fcu, fcu->bezt))
+ return 0;
+
+ /* set the F-Curve into the editdata so that it can be accessed */
+ if (ked) {
+ ked->fcu = fcu;
+ ked->curIndex = 0;
+ ked->curflags = ok;
+ }
+
+ /* if function to apply to bezier curves is set, then loop through executing it on beztriples */
+ if (key_cb) {
+ /* if there's a validation func, include that check in the loop
+ * (this is should be more efficient than checking for it in every loop)
+ */
+ if (key_ok) {
+ for (bezt = fcu->bezt, i = 0; i < fcu->totvert; bezt++, i++) {
+ if (ked) {
+ /* advance the index, and reset the ok flags (to not influence the result) */
+ ked->curIndex = i;
+ ked->curflags = 0;
+ }
+
+ /* Only operate on this BezTriple if it fulfills the criteria of the validation func */
+ if ((ok = key_ok(ked, bezt))) {
+ if (ked)
+ ked->curflags = ok;
+
+ /* Exit with return-code '1' if function returns positive
+ * This is useful if finding if some BezTriple satisfies a condition.
+ */
+ if (key_cb(ked, bezt))
+ return 1;
+ }
+ }
+ }
+ else {
+ for (bezt = fcu->bezt, i = 0; i < fcu->totvert; bezt++, i++) {
+ if (ked)
+ ked->curIndex = i;
+
+ /* Exit with return-code '1' if function returns positive
+ * This is useful if finding if some BezTriple satisfies a condition.
+ */
+ if (key_cb(ked, bezt))
+ return 1;
+ }
+ }
+ }
+
+ /* unset the F-Curve from the editdata now that it's done */
+ if (ked) {
+ ked->fcu = NULL;
+ ked->curIndex = 0;
+ ked->curflags = 0;
+ }
+
+ /* if fcu_cb (F-Curve post-editing callback) has been specified then execute it */
+ if (fcu_cb)
+ fcu_cb(fcu);
+
+ /* done */
+ return 0;
}
/* -------------------------------- Further Abstracted (Not Exposed Directly) ----------------------------- */
/* This function is used to loop over the keyframe data in an Action Group */
-static short agrp_keyframes_loop(KeyframeEditData *ked, bActionGroup *agrp, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
+static short agrp_keyframes_loop(KeyframeEditData *ked,
+ bActionGroup *agrp,
+ KeyframeEditFunc key_ok,
+ KeyframeEditFunc key_cb,
+ FcuEditFunc fcu_cb)
{
- FCurve *fcu;
+ FCurve *fcu;
- /* sanity check */
- if (agrp == NULL)
- return 0;
+ /* sanity check */
+ if (agrp == NULL)
+ return 0;
- /* only iterate over the F-Curves that are in this group */
- for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next) {
- if (ANIM_fcurve_keyframes_loop(ked, fcu, key_ok, key_cb, fcu_cb))
- return 1;
- }
+ /* only iterate over the F-Curves that are in this group */
+ for (fcu = agrp->channels.first; fcu && fcu->grp == agrp; fcu = fcu->next) {
+ if (ANIM_fcurve_keyframes_loop(ked, fcu, key_ok, key_cb, fcu_cb))
+ return 1;
+ }
- return 0;
+ return 0;
}
/* This function is used to loop over the keyframe data in an Action */
-static short act_keyframes_loop(KeyframeEditData *ked, bAction *act, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
+static short act_keyframes_loop(KeyframeEditData *ked,
+ bAction *act,
+ KeyframeEditFunc key_ok,
+ KeyframeEditFunc key_cb,
+ FcuEditFunc fcu_cb)
{
- FCurve *fcu;
+ FCurve *fcu;
- /* sanity check */
- if (act == NULL)
- return 0;
+ /* sanity check */
+ if (act == NULL)
+ return 0;
- /* just loop through all F-Curves */
- for (fcu = act->curves.first; fcu; fcu = fcu->next) {
- if (ANIM_fcurve_keyframes_loop(ked, fcu, key_ok, key_cb, fcu_cb))
- return 1;
- }
+ /* just loop through all F-Curves */
+ for (fcu = act->curves.first; fcu; fcu = fcu->next) {
+ if (ANIM_fcurve_keyframes_loop(ked, fcu, key_ok, key_cb, fcu_cb))
+ return 1;
+ }
- return 0;
+ return 0;
}
/* This function is used to loop over the keyframe data in an Object */
-static short ob_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads, Object *ob, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
+static short ob_keyframes_loop(KeyframeEditData *ked,
+ bDopeSheet *ads,
+ Object *ob,
+ KeyframeEditFunc key_ok,
+ KeyframeEditFunc key_cb,
+ FcuEditFunc fcu_cb)
{
- bAnimContext ac = {NULL};
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- int ret = 0;
+ bAnimContext ac = {NULL};
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ int ret = 0;
- bAnimListElem dummychan = {NULL};
- Base dummybase = {NULL};
+ bAnimListElem dummychan = {NULL};
+ Base dummybase = {NULL};
- if (ob == NULL)
- return 0;
+ if (ob == NULL)
+ return 0;
- /* create a dummy wrapper data to work with */
- dummybase.object = ob;
+ /* create a dummy wrapper data to work with */
+ dummybase.object = ob;
- dummychan.type = ANIMTYPE_OBJECT;
- dummychan.data = &dummybase;
- dummychan.id = &ob->id;
- dummychan.adt = ob->adt;
+ dummychan.type = ANIMTYPE_OBJECT;
+ dummychan.data = &dummybase;
+ dummychan.id = &ob->id;
+ dummychan.adt = ob->adt;
- ac.ads = ads;
- ac.data = &dummychan;
- ac.datatype = ANIMCONT_CHANNEL;
+ ac.ads = ads;
+ ac.data = &dummychan;
+ ac.datatype = ANIMCONT_CHANNEL;
- /* get F-Curves to take keyframes from */
- filter = ANIMFILTER_DATA_VISIBLE; // curves only
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* get F-Curves to take keyframes from */
+ filter = ANIMFILTER_DATA_VISIBLE; // curves only
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- /* loop through each F-Curve, applying the operation as required, but stopping on the first one */
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ANIM_fcurve_keyframes_loop(ked, (FCurve *)ale->data, key_ok, key_cb, fcu_cb)) {
- ret = 1;
- break;
- }
- }
+ /* loop through each F-Curve, applying the operation as required, but stopping on the first one */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (ANIM_fcurve_keyframes_loop(ked, (FCurve *)ale->data, key_ok, key_cb, fcu_cb)) {
+ ret = 1;
+ break;
+ }
+ }
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_freelist(&anim_data);
- /* return return code - defaults to zero if nothing happened */
- return ret;
+ /* return return code - defaults to zero if nothing happened */
+ return ret;
}
/* This function is used to loop over the keyframe data in a Scene */
-static short scene_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads, Scene *sce, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
+static short scene_keyframes_loop(KeyframeEditData *ked,
+ bDopeSheet *ads,
+ Scene *sce,
+ KeyframeEditFunc key_ok,
+ KeyframeEditFunc key_cb,
+ FcuEditFunc fcu_cb)
{
- bAnimContext ac = {NULL};
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
- int ret = 0;
+ bAnimContext ac = {NULL};
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+ int ret = 0;
- bAnimListElem dummychan = {NULL};
+ bAnimListElem dummychan = {NULL};
- if (sce == NULL)
- return 0;
+ if (sce == NULL)
+ return 0;
- /* create a dummy wrapper data to work with */
- dummychan.type = ANIMTYPE_SCENE;
- dummychan.data = sce;
- dummychan.id = &sce->id;
- dummychan.adt = sce->adt;
+ /* create a dummy wrapper data to work with */
+ dummychan.type = ANIMTYPE_SCENE;
+ dummychan.data = sce;
+ dummychan.id = &sce->id;
+ dummychan.adt = sce->adt;
- ac.ads = ads;
- ac.data = &dummychan;
- ac.datatype = ANIMCONT_CHANNEL;
+ ac.ads = ads;
+ ac.data = &dummychan;
+ ac.datatype = ANIMCONT_CHANNEL;
- /* get F-Curves to take keyframes from */
- filter = ANIMFILTER_DATA_VISIBLE; // curves only
- ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ /* get F-Curves to take keyframes from */
+ filter = ANIMFILTER_DATA_VISIBLE; // curves only
+ ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- /* loop through each F-Curve, applying the operation as required, but stopping on the first one */
- for (ale = anim_data.first; ale; ale = ale->next) {
- if (ANIM_fcurve_keyframes_loop(ked, (FCurve *)ale->data, key_ok, key_cb, fcu_cb)) {
- ret = 1;
- break;
- }
- }
+ /* loop through each F-Curve, applying the operation as required, but stopping on the first one */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ if (ANIM_fcurve_keyframes_loop(ked, (FCurve *)ale->data, key_ok, key_cb, fcu_cb)) {
+ ret = 1;
+ break;
+ }
+ }
- ANIM_animdata_freelist(&anim_data);
+ ANIM_animdata_freelist(&anim_data);
- /* return return code - defaults to zero if nothing happened */
- return ret;
+ /* return return code - defaults to zero if nothing happened */
+ return ret;
}
/* This function is used to loop over the keyframe data in a DopeSheet summary */
-static short summary_keyframes_loop(KeyframeEditData *ked, bAnimContext *ac, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
-{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter, ret_code = 0;
-
- /* sanity check */
- if (ac == NULL)
- return 0;
-
- /* get F-Curves to take keyframes from */
- filter = ANIMFILTER_DATA_VISIBLE;
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* loop through each F-Curve, working on the keyframes until the first curve aborts */
- for (ale = anim_data.first; ale; ale = ale->next) {
- switch (ale->datatype) {
- case ALE_MASKLAY:
- case ALE_GPFRAME:
- break;
-
- case ALE_FCURVE:
- default:
- {
- if (ked && ked->iterflags) {
- /* make backups of the current values, so that a localised fix
- * (e.g. NLA time remapping) can be applied to these values
- */
- float f1 = ked->f1;
- float f2 = ked->f2;
-
- if (ked->iterflags & (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP)) {
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
-
- if (ked->iterflags & KED_F1_NLA_UNMAP)
- ked->f1 = BKE_nla_tweakedit_remap(adt, f1, NLATIME_CONVERT_UNMAP);
- if (ked->iterflags & KED_F2_NLA_UNMAP)
- ked->f2 = BKE_nla_tweakedit_remap(adt, f2, NLATIME_CONVERT_UNMAP);
- }
-
- /* now operate on the channel as per normal */
- ret_code = ANIM_fcurve_keyframes_loop(ked, ale->data, key_ok, key_cb, fcu_cb);
-
- /* reset */
- ked->f1 = f1;
- ked->f2 = f2;
- }
- else {
- /* no special handling required... */
- ret_code = ANIM_fcurve_keyframes_loop(ked, ale->data, key_ok, key_cb, fcu_cb);
- }
- break;
- }
- }
-
- if (ret_code)
- break;
- }
-
- ANIM_animdata_freelist(&anim_data);
-
- return ret_code;
+static short summary_keyframes_loop(KeyframeEditData *ked,
+ bAnimContext *ac,
+ KeyframeEditFunc key_ok,
+ KeyframeEditFunc key_cb,
+ FcuEditFunc fcu_cb)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter, ret_code = 0;
+
+ /* sanity check */
+ if (ac == NULL)
+ return 0;
+
+ /* get F-Curves to take keyframes from */
+ filter = ANIMFILTER_DATA_VISIBLE;
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* loop through each F-Curve, working on the keyframes until the first curve aborts */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ switch (ale->datatype) {
+ case ALE_MASKLAY:
+ case ALE_GPFRAME:
+ break;
+
+ case ALE_FCURVE:
+ default: {
+ if (ked && ked->iterflags) {
+ /* make backups of the current values, so that a localised fix
+ * (e.g. NLA time remapping) can be applied to these values
+ */
+ float f1 = ked->f1;
+ float f2 = ked->f2;
+
+ if (ked->iterflags & (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP)) {
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+
+ if (ked->iterflags & KED_F1_NLA_UNMAP)
+ ked->f1 = BKE_nla_tweakedit_remap(adt, f1, NLATIME_CONVERT_UNMAP);
+ if (ked->iterflags & KED_F2_NLA_UNMAP)
+ ked->f2 = BKE_nla_tweakedit_remap(adt, f2, NLATIME_CONVERT_UNMAP);
+ }
+
+ /* now operate on the channel as per normal */
+ ret_code = ANIM_fcurve_keyframes_loop(ked, ale->data, key_ok, key_cb, fcu_cb);
+
+ /* reset */
+ ked->f1 = f1;
+ ked->f2 = f2;
+ }
+ else {
+ /* no special handling required... */
+ ret_code = ANIM_fcurve_keyframes_loop(ked, ale->data, key_ok, key_cb, fcu_cb);
+ }
+ break;
+ }
+ }
+
+ if (ret_code)
+ break;
+ }
+
+ ANIM_animdata_freelist(&anim_data);
+
+ return ret_code;
}
/* --- */
/* This function is used to apply operation to all keyframes, regardless of the type */
-short ANIM_animchannel_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads, bAnimListElem *ale, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
-{
- /* sanity checks */
- if (ale == NULL)
- return 0;
-
- /* method to use depends on the type of keyframe data */
- switch (ale->datatype) {
- /* direct keyframe data (these loops are exposed) */
- case ALE_FCURVE: /* F-Curve */
- return ANIM_fcurve_keyframes_loop(ked, ale->key_data, key_ok, key_cb, fcu_cb);
-
- /* indirect 'summaries' (these are not exposed directly)
- * NOTE: must keep this code in sync with the drawing code and also the filtering code!
- */
- case ALE_GROUP: /* action group */
- return agrp_keyframes_loop(ked, (bActionGroup *)ale->data, key_ok, key_cb, fcu_cb);
- case ALE_ACT: /* action */
- return act_keyframes_loop(ked, (bAction *)ale->key_data, key_ok, key_cb, fcu_cb);
-
- case ALE_OB: /* object */
- return ob_keyframes_loop(ked, ads, (Object *)ale->key_data, key_ok, key_cb, fcu_cb);
- case ALE_SCE: /* scene */
- return scene_keyframes_loop(ked, ads, (Scene *)ale->data, key_ok, key_cb, fcu_cb);
- case ALE_ALL: /* 'all' (DopeSheet summary) */
- return summary_keyframes_loop(ked, (bAnimContext *)ale->data, key_ok, key_cb, fcu_cb);
- }
-
- return 0;
+short ANIM_animchannel_keyframes_loop(KeyframeEditData *ked,
+ bDopeSheet *ads,
+ bAnimListElem *ale,
+ KeyframeEditFunc key_ok,
+ KeyframeEditFunc key_cb,
+ FcuEditFunc fcu_cb)
+{
+ /* sanity checks */
+ if (ale == NULL)
+ return 0;
+
+ /* method to use depends on the type of keyframe data */
+ switch (ale->datatype) {
+ /* direct keyframe data (these loops are exposed) */
+ case ALE_FCURVE: /* F-Curve */
+ return ANIM_fcurve_keyframes_loop(ked, ale->key_data, key_ok, key_cb, fcu_cb);
+
+ /* indirect 'summaries' (these are not exposed directly)
+ * NOTE: must keep this code in sync with the drawing code and also the filtering code!
+ */
+ case ALE_GROUP: /* action group */
+ return agrp_keyframes_loop(ked, (bActionGroup *)ale->data, key_ok, key_cb, fcu_cb);
+ case ALE_ACT: /* action */
+ return act_keyframes_loop(ked, (bAction *)ale->key_data, key_ok, key_cb, fcu_cb);
+
+ case ALE_OB: /* object */
+ return ob_keyframes_loop(ked, ads, (Object *)ale->key_data, key_ok, key_cb, fcu_cb);
+ case ALE_SCE: /* scene */
+ return scene_keyframes_loop(ked, ads, (Scene *)ale->data, key_ok, key_cb, fcu_cb);
+ case ALE_ALL: /* 'all' (DopeSheet summary) */
+ return summary_keyframes_loop(ked, (bAnimContext *)ale->data, key_ok, key_cb, fcu_cb);
+ }
+
+ return 0;
}
/* This function is used to apply operation to all keyframes,
* regardless of the type without needed an AnimListElem wrapper */
-short ANIM_animchanneldata_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads, void *data, int keytype, KeyframeEditFunc key_ok, KeyframeEditFunc key_cb, FcuEditFunc fcu_cb)
-{
- /* sanity checks */
- if (data == NULL)
- return 0;
-
- /* method to use depends on the type of keyframe data */
- switch (keytype) {
- /* direct keyframe data (these loops are exposed) */
- case ALE_FCURVE: /* F-Curve */
- return ANIM_fcurve_keyframes_loop(ked, data, key_ok, key_cb, fcu_cb);
-
- /* indirect 'summaries' (these are not exposed directly)
- * NOTE: must keep this code in sync with the drawing code and also the filtering code!
- */
- case ALE_GROUP: /* action group */
- return agrp_keyframes_loop(ked, (bActionGroup *)data, key_ok, key_cb, fcu_cb);
- case ALE_ACT: /* action */
- return act_keyframes_loop(ked, (bAction *)data, key_ok, key_cb, fcu_cb);
-
- case ALE_OB: /* object */
- return ob_keyframes_loop(ked, ads, (Object *)data, key_ok, key_cb, fcu_cb);
- case ALE_SCE: /* scene */
- return scene_keyframes_loop(ked, ads, (Scene *)data, key_ok, key_cb, fcu_cb);
- case ALE_ALL: /* 'all' (DopeSheet summary) */
- return summary_keyframes_loop(ked, (bAnimContext *)data, key_ok, key_cb, fcu_cb);
- }
-
- return 0;
+short ANIM_animchanneldata_keyframes_loop(KeyframeEditData *ked,
+ bDopeSheet *ads,
+ void *data,
+ int keytype,
+ KeyframeEditFunc key_ok,
+ KeyframeEditFunc key_cb,
+ FcuEditFunc fcu_cb)
+{
+ /* sanity checks */
+ if (data == NULL)
+ return 0;
+
+ /* method to use depends on the type of keyframe data */
+ switch (keytype) {
+ /* direct keyframe data (these loops are exposed) */
+ case ALE_FCURVE: /* F-Curve */
+ return ANIM_fcurve_keyframes_loop(ked, data, key_ok, key_cb, fcu_cb);
+
+ /* indirect 'summaries' (these are not exposed directly)
+ * NOTE: must keep this code in sync with the drawing code and also the filtering code!
+ */
+ case ALE_GROUP: /* action group */
+ return agrp_keyframes_loop(ked, (bActionGroup *)data, key_ok, key_cb, fcu_cb);
+ case ALE_ACT: /* action */
+ return act_keyframes_loop(ked, (bAction *)data, key_ok, key_cb, fcu_cb);
+
+ case ALE_OB: /* object */
+ return ob_keyframes_loop(ked, ads, (Object *)data, key_ok, key_cb, fcu_cb);
+ case ALE_SCE: /* scene */
+ return scene_keyframes_loop(ked, ads, (Scene *)data, key_ok, key_cb, fcu_cb);
+ case ALE_ALL: /* 'all' (DopeSheet summary) */
+ return summary_keyframes_loop(ked, (bAnimContext *)data, key_ok, key_cb, fcu_cb);
+ }
+
+ return 0;
}
/* ************************************************************************** */
@@ -403,23 +442,23 @@ short ANIM_animchanneldata_keyframes_loop(KeyframeEditData *ked, bDopeSheet *ads
// used to be recalc_*_ipos() where * was object or action
void ANIM_editkeyframes_refresh(bAnimContext *ac)
{
- ListBase anim_data = {NULL, NULL};
- bAnimListElem *ale;
- int filter;
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
- /* filter animation data */
- filter = ANIMFILTER_DATA_VISIBLE;
- ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+ /* filter animation data */
+ filter = ANIMFILTER_DATA_VISIBLE;
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
- /* Loop over F-Curves that are likely to have been edited, and tag them to
- * ensure the keyframes are in order and handles are in a valid position. */
- for (ale = anim_data.first; ale; ale = ale->next) {
- ale->update |= ANIM_UPDATE_DEPS | ANIM_UPDATE_HANDLES | ANIM_UPDATE_ORDER;
- }
+ /* Loop over F-Curves that are likely to have been edited, and tag them to
+ * ensure the keyframes are in order and handles are in a valid position. */
+ for (ale = anim_data.first; ale; ale = ale->next) {
+ ale->update |= ANIM_UPDATE_DEPS | ANIM_UPDATE_HANDLES | ANIM_UPDATE_ORDER;
+ }
- /* free temp data */
- ANIM_animdata_update(ac, &anim_data);
- ANIM_animdata_freelist(&anim_data);
+ /* free temp data */
+ ANIM_animdata_update(ac, &anim_data);
+ ANIM_animdata_freelist(&anim_data);
}
/* ************************************************************************** */
@@ -433,271 +472,267 @@ void ANIM_editkeyframes_refresh(bAnimContext *ac)
* - requires that a var, of type short, is named 'ok', and has been initialized to 0
*/
#define KEYFRAME_OK_CHECKS(check) \
- { \
- CHECK_TYPE(ok, short); \
- if (check(1)) \
- ok |= KEYFRAME_OK_KEY; \
- \
- if (ked && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) { \
- if (check(0)) \
- ok |= KEYFRAME_OK_H1; \
- if (check(2)) \
- ok |= KEYFRAME_OK_H2; \
- } \
- } (void)0
+ { \
+ CHECK_TYPE(ok, short); \
+ if (check(1)) \
+ ok |= KEYFRAME_OK_KEY; \
+\
+ if (ked && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) { \
+ if (check(0)) \
+ ok |= KEYFRAME_OK_H1; \
+ if (check(2)) \
+ ok |= KEYFRAME_OK_H2; \
+ } \
+ } \
+ (void)0
/* ------------------------ */
static short ok_bezier_frame(KeyframeEditData *ked, BezTriple *bezt)
{
- short ok = 0;
+ short ok = 0;
- /* frame is stored in f1 property (this float accuracy check may need to be dropped?) */
+ /* frame is stored in f1 property (this float accuracy check may need to be dropped?) */
#define KEY_CHECK_OK(_index) IS_EQF(bezt->vec[_index][0], ked->f1)
- KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
+ KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
- /* return ok flags */
- return ok;
+ /* return ok flags */
+ return ok;
}
static short ok_bezier_framerange(KeyframeEditData *ked, BezTriple *bezt)
{
- short ok = 0;
+ short ok = 0;
- /* frame range is stored in float properties */
+ /* frame range is stored in float properties */
#define KEY_CHECK_OK(_index) ((bezt->vec[_index][0] > ked->f1) && (bezt->vec[_index][0] < ked->f2))
- KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
+ KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
- /* return ok flags */
- return ok;
+ /* return ok flags */
+ return ok;
}
static short ok_bezier_selected(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- /* this macro checks all beztriple handles for selection...
- * only one of the verts has to be selected for this to be ok...
- */
- if (BEZT_ISSEL_ANY(bezt))
- return KEYFRAME_OK_ALL;
- else
- return 0;
+ /* this macro checks all beztriple handles for selection...
+ * only one of the verts has to be selected for this to be ok...
+ */
+ if (BEZT_ISSEL_ANY(bezt))
+ return KEYFRAME_OK_ALL;
+ else
+ return 0;
}
static short ok_bezier_value(KeyframeEditData *ked, BezTriple *bezt)
{
- short ok = 0;
+ short ok = 0;
- /* value is stored in f1 property
- * - this float accuracy check may need to be dropped?
- * - should value be stored in f2 instead so that we won't have conflicts when using f1 for frames too?
- */
+ /* value is stored in f1 property
+ * - this float accuracy check may need to be dropped?
+ * - should value be stored in f2 instead so that we won't have conflicts when using f1 for frames too?
+ */
#define KEY_CHECK_OK(_index) IS_EQF(bezt->vec[_index][1], ked->f1)
- KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
+ KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
- /* return ok flags */
- return ok;
+ /* return ok flags */
+ return ok;
}
static short ok_bezier_valuerange(KeyframeEditData *ked, BezTriple *bezt)
{
- short ok = 0;
+ short ok = 0;
- /* value range is stored in float properties */
+ /* value range is stored in float properties */
#define KEY_CHECK_OK(_index) ((bezt->vec[_index][1] > ked->f1) && (bezt->vec[_index][1] < ked->f2))
- KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
+ KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
- /* return ok flags */
- return ok;
+ /* return ok flags */
+ return ok;
}
static short ok_bezier_region(KeyframeEditData *ked, BezTriple *bezt)
{
- /* rect is stored in data property (it's of type rectf, but may not be set) */
- if (ked->data) {
- short ok = 0;
+ /* rect is stored in data property (it's of type rectf, but may not be set) */
+ if (ked->data) {
+ short ok = 0;
#define KEY_CHECK_OK(_index) BLI_rctf_isect_pt_v(ked->data, bezt->vec[_index])
- KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
+ KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
- /* return ok flags */
- return ok;
- }
- else
- return 0;
+ /* return ok flags */
+ return ok;
+ }
+ else
+ return 0;
}
/**
* Called from #ok_bezier_region_lasso and #ok_bezier_channel_lasso
*/
-bool keyframe_region_lasso_test(
- const KeyframeEdit_LassoData *data_lasso,
- const float xy[2])
+bool keyframe_region_lasso_test(const KeyframeEdit_LassoData *data_lasso, const float xy[2])
{
- if (BLI_rctf_isect_pt_v(data_lasso->rectf_scaled, xy)) {
- float xy_view[2];
+ if (BLI_rctf_isect_pt_v(data_lasso->rectf_scaled, xy)) {
+ float xy_view[2];
- BLI_rctf_transform_pt_v(data_lasso->rectf_view, data_lasso->rectf_scaled, xy_view, xy);
+ BLI_rctf_transform_pt_v(data_lasso->rectf_view, data_lasso->rectf_scaled, xy_view, xy);
- if (BLI_lasso_is_point_inside(data_lasso->mcords, data_lasso->mcords_tot, xy_view[0], xy_view[1], INT_MAX)) {
- return true;
- }
- }
+ if (BLI_lasso_is_point_inside(
+ data_lasso->mcords, data_lasso->mcords_tot, xy_view[0], xy_view[1], INT_MAX)) {
+ return true;
+ }
+ }
- return false;
+ return false;
}
static short ok_bezier_region_lasso(KeyframeEditData *ked, BezTriple *bezt)
{
- /* check for lasso customdata (KeyframeEdit_LassoData) */
- if (ked->data) {
- short ok = 0;
+ /* check for lasso customdata (KeyframeEdit_LassoData) */
+ if (ked->data) {
+ short ok = 0;
#define KEY_CHECK_OK(_index) keyframe_region_lasso_test(ked->data, bezt->vec[_index])
- KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
+ KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
- /* return ok flags */
- return ok;
- }
- else
- return 0;
+ /* return ok flags */
+ return ok;
+ }
+ else
+ return 0;
}
static short ok_bezier_channel_lasso(KeyframeEditData *ked, BezTriple *bezt)
{
- /* check for lasso customdata (KeyframeEdit_LassoData) */
- if (ked->data) {
- KeyframeEdit_LassoData *data = ked->data;
- float pt[2];
+ /* check for lasso customdata (KeyframeEdit_LassoData) */
+ if (ked->data) {
+ KeyframeEdit_LassoData *data = ked->data;
+ float pt[2];
- /* late-binding remap of the x values (for summary channels) */
- /* XXX: Ideally we reset, but it should be fine just leaving it as-is
- * as the next channel will reset it properly, while the next summary-channel
- * curve will also reset by itself...
- */
- if (ked->iterflags & (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP)) {
- data->rectf_scaled->xmin = ked->f1;
- data->rectf_scaled->xmax = ked->f2;
- }
+ /* late-binding remap of the x values (for summary channels) */
+ /* XXX: Ideally we reset, but it should be fine just leaving it as-is
+ * as the next channel will reset it properly, while the next summary-channel
+ * curve will also reset by itself...
+ */
+ if (ked->iterflags & (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP)) {
+ data->rectf_scaled->xmin = ked->f1;
+ data->rectf_scaled->xmax = ked->f2;
+ }
- /* only use the x-coordinate of the point; the y is the channel range... */
- pt[0] = bezt->vec[1][0];
- pt[1] = ked->channel_y;
+ /* only use the x-coordinate of the point; the y is the channel range... */
+ pt[0] = bezt->vec[1][0];
+ pt[1] = ked->channel_y;
- if (keyframe_region_lasso_test(data, pt))
- return KEYFRAME_OK_KEY;
- }
- return 0;
+ if (keyframe_region_lasso_test(data, pt))
+ return KEYFRAME_OK_KEY;
+ }
+ return 0;
}
/**
* Called from #ok_bezier_region_circle and #ok_bezier_channel_circle
*/
-bool keyframe_region_circle_test(
- const KeyframeEdit_CircleData *data_circle,
- const float xy[2])
+bool keyframe_region_circle_test(const KeyframeEdit_CircleData *data_circle, const float xy[2])
{
- if (BLI_rctf_isect_pt_v(data_circle->rectf_scaled, xy)) {
- float xy_view[2];
+ if (BLI_rctf_isect_pt_v(data_circle->rectf_scaled, xy)) {
+ float xy_view[2];
- BLI_rctf_transform_pt_v(data_circle->rectf_view, data_circle->rectf_scaled, xy_view, xy);
+ BLI_rctf_transform_pt_v(data_circle->rectf_view, data_circle->rectf_scaled, xy_view, xy);
- xy_view[0] = xy_view[0] - data_circle->mval[0];
- xy_view[1] = xy_view[1] - data_circle->mval[1];
- return len_squared_v2(xy_view) < data_circle->radius_squared;
- }
+ xy_view[0] = xy_view[0] - data_circle->mval[0];
+ xy_view[1] = xy_view[1] - data_circle->mval[1];
+ return len_squared_v2(xy_view) < data_circle->radius_squared;
+ }
- return false;
+ return false;
}
-
static short ok_bezier_region_circle(KeyframeEditData *ked, BezTriple *bezt)
{
- /* check for circle select customdata (KeyframeEdit_CircleData) */
- if (ked->data) {
- short ok = 0;
+ /* check for circle select customdata (KeyframeEdit_CircleData) */
+ if (ked->data) {
+ short ok = 0;
#define KEY_CHECK_OK(_index) keyframe_region_circle_test(ked->data, bezt->vec[_index])
- KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
+ KEYFRAME_OK_CHECKS(KEY_CHECK_OK);
#undef KEY_CHECK_OK
- /* return ok flags */
- return ok;
- }
- else
- return 0;
+ /* return ok flags */
+ return ok;
+ }
+ else
+ return 0;
}
static short ok_bezier_channel_circle(KeyframeEditData *ked, BezTriple *bezt)
{
- /* check for circle select customdata (KeyframeEdit_CircleData) */
- if (ked->data) {
- KeyframeEdit_CircleData *data = ked->data;
- float pt[2];
+ /* check for circle select customdata (KeyframeEdit_CircleData) */
+ if (ked->data) {
+ KeyframeEdit_CircleData *data = ked->data;
+ float pt[2];
- /* late-binding remap of the x values (for summary channels) */
- /* XXX: Ideally we reset, but it should be fine just leaving it as-is
- * as the next channel will reset it properly, while the next summary-channel
- * curve will also reset by itself...
- */
- if (ked->iterflags & (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP)) {
- data->rectf_scaled->xmin = ked->f1;
- data->rectf_scaled->xmax = ked->f2;
- }
+ /* late-binding remap of the x values (for summary channels) */
+ /* XXX: Ideally we reset, but it should be fine just leaving it as-is
+ * as the next channel will reset it properly, while the next summary-channel
+ * curve will also reset by itself...
+ */
+ if (ked->iterflags & (KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP)) {
+ data->rectf_scaled->xmin = ked->f1;
+ data->rectf_scaled->xmax = ked->f2;
+ }
- /* only use the x-coordinate of the point; the y is the channel range... */
- pt[0] = bezt->vec[1][0];
- pt[1] = ked->channel_y;
+ /* only use the x-coordinate of the point; the y is the channel range... */
+ pt[0] = bezt->vec[1][0];
+ pt[1] = ked->channel_y;
- if (keyframe_region_circle_test(data, pt))
- return KEYFRAME_OK_KEY;
- }
- return 0;
+ if (keyframe_region_circle_test(data, pt))
+ return KEYFRAME_OK_KEY;
+ }
+ return 0;
}
-
KeyframeEditFunc ANIM_editkeyframes_ok(short mode)
{
- /* eEditKeyframes_Validate */
- switch (mode) {
- case BEZT_OK_FRAME:
- /* only if bezt falls on the right frame (float) */
- return ok_bezier_frame;
- case BEZT_OK_FRAMERANGE:
- /* only if bezt falls within the specified frame range (floats) */
- return ok_bezier_framerange;
- case BEZT_OK_SELECTED:
- /* only if bezt is selected (self) */
- return ok_bezier_selected;
- case BEZT_OK_VALUE:
- /* only if bezt value matches (float) */
- return ok_bezier_value;
- case BEZT_OK_VALUERANGE:
- /* only if bezier falls within the specified value range (floats) */
- return ok_bezier_valuerange;
- case BEZT_OK_REGION:
- /* only if bezier falls within the specified rect (data -> rectf) */
- return ok_bezier_region;
- case BEZT_OK_REGION_LASSO:
- /* only if the point falls within KeyframeEdit_LassoData defined data */
- return ok_bezier_region_lasso;
- case BEZT_OK_REGION_CIRCLE:
- /* only if the point falls within KeyframeEdit_CircleData defined data */
- return ok_bezier_region_circle;
- case BEZT_OK_CHANNEL_LASSO:
- /* same as BEZT_OK_REGION_LASSO, but we're only using the x-value of the points */
- return ok_bezier_channel_lasso;
- case BEZT_OK_CHANNEL_CIRCLE:
- /* same as BEZT_OK_REGION_CIRCLE, but we're only using the x-value of the points */
- return ok_bezier_channel_circle;
- default: /* nothing was ok */
- return NULL;
- }
+ /* eEditKeyframes_Validate */
+ switch (mode) {
+ case BEZT_OK_FRAME:
+ /* only if bezt falls on the right frame (float) */
+ return ok_bezier_frame;
+ case BEZT_OK_FRAMERANGE:
+ /* only if bezt falls within the specified frame range (floats) */
+ return ok_bezier_framerange;
+ case BEZT_OK_SELECTED:
+ /* only if bezt is selected (self) */
+ return ok_bezier_selected;
+ case BEZT_OK_VALUE:
+ /* only if bezt value matches (float) */
+ return ok_bezier_value;
+ case BEZT_OK_VALUERANGE:
+ /* only if bezier falls within the specified value range (floats) */
+ return ok_bezier_valuerange;
+ case BEZT_OK_REGION:
+ /* only if bezier falls within the specified rect (data -> rectf) */
+ return ok_bezier_region;
+ case BEZT_OK_REGION_LASSO:
+ /* only if the point falls within KeyframeEdit_LassoData defined data */
+ return ok_bezier_region_lasso;
+ case BEZT_OK_REGION_CIRCLE:
+ /* only if the point falls within KeyframeEdit_CircleData defined data */
+ return ok_bezier_region_circle;
+ case BEZT_OK_CHANNEL_LASSO:
+ /* same as BEZT_OK_REGION_LASSO, but we're only using the x-value of the points */
+ return ok_bezier_channel_lasso;
+ case BEZT_OK_CHANNEL_CIRCLE:
+ /* same as BEZT_OK_REGION_CIRCLE, but we're only using the x-value of the points */
+ return ok_bezier_channel_circle;
+ default: /* nothing was ok */
+ return NULL;
+ }
}
/* ******************************************* */
@@ -709,36 +744,36 @@ KeyframeEditFunc ANIM_editkeyframes_ok(short mode)
*/
short bezt_calc_average(KeyframeEditData *ked, BezTriple *bezt)
{
- /* only if selected */
- if (bezt->f2 & SELECT) {
- /* store average time in float 1 (only do rounding at last step) */
- ked->f1 += bezt->vec[1][0];
+ /* only if selected */
+ if (bezt->f2 & SELECT) {
+ /* store average time in float 1 (only do rounding at last step) */
+ ked->f1 += bezt->vec[1][0];
- /* store average value in float 2 (only do rounding at last step)
- * - this isn't always needed, but some operators may also require this
- */
- ked->f2 += bezt->vec[1][1];
+ /* store average value in float 2 (only do rounding at last step)
+ * - this isn't always needed, but some operators may also require this
+ */
+ ked->f2 += bezt->vec[1][1];
- /* increment number of items */
- ked->i1++;
- }
+ /* increment number of items */
+ ked->i1++;
+ }
- return 0;
+ return 0;
}
/* helper callback for columnselect_<animeditor>_keys() -> populate
* list CfraElems with frame numbers from selected beztriples */
short bezt_to_cfraelem(KeyframeEditData *ked, BezTriple *bezt)
{
- /* only if selected */
- if (bezt->f2 & SELECT) {
- CfraElem *ce = MEM_callocN(sizeof(CfraElem), "cfraElem");
- BLI_addtail(&ked->list, ce);
+ /* only if selected */
+ if (bezt->f2 & SELECT) {
+ CfraElem *ce = MEM_callocN(sizeof(CfraElem), "cfraElem");
+ BLI_addtail(&ked->list, ce);
- ce->cfra = bezt->vec[1][0];
- }
+ ce->cfra = bezt->vec[1][0];
+ }
- return 0;
+ return 0;
}
/* used to remap times from one range to another
@@ -746,15 +781,15 @@ short bezt_to_cfraelem(KeyframeEditData *ked, BezTriple *bezt)
*/
void bezt_remap_times(KeyframeEditData *ked, BezTriple *bezt)
{
- KeyframeEditCD_Remap *rmap = (KeyframeEditCD_Remap *)ked->data;
- const float scale = (rmap->newMax - rmap->newMin) / (rmap->oldMax - rmap->oldMin);
+ KeyframeEditCD_Remap *rmap = (KeyframeEditCD_Remap *)ked->data;
+ const float scale = (rmap->newMax - rmap->newMin) / (rmap->oldMax - rmap->oldMin);
- /* perform transform on all three handles unless indicated otherwise */
- // TODO: need to include some checks for that
+ /* perform transform on all three handles unless indicated otherwise */
+ // TODO: need to include some checks for that
- bezt->vec[0][0] = scale * (bezt->vec[0][0] - rmap->oldMin) + rmap->newMin;
- bezt->vec[1][0] = scale * (bezt->vec[1][0] - rmap->oldMin) + rmap->newMin;
- bezt->vec[2][0] = scale * (bezt->vec[2][0] - rmap->oldMin) + rmap->newMin;
+ bezt->vec[0][0] = scale * (bezt->vec[0][0] - rmap->oldMin) + rmap->newMin;
+ bezt->vec[1][0] = scale * (bezt->vec[1][0] - rmap->oldMin) + rmap->newMin;
+ bezt->vec[2][0] = scale * (bezt->vec[2][0] - rmap->oldMin) + rmap->newMin;
}
/* ******************************************* */
@@ -763,199 +798,201 @@ void bezt_remap_times(KeyframeEditData *ked, BezTriple *bezt)
/* snaps the keyframe to the nearest frame */
static short snap_bezier_nearest(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->vec[1][0] = (float)(floorf(bezt->vec[1][0] + 0.5f));
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->vec[1][0] = (float)(floorf(bezt->vec[1][0] + 0.5f));
+ return 0;
}
/* snaps the keyframe to the nearest second */
static short snap_bezier_nearestsec(KeyframeEditData *ked, BezTriple *bezt)
{
- const Scene *scene = ked->scene;
- const float secf = (float)FPS;
+ const Scene *scene = ked->scene;
+ const float secf = (float)FPS;
- if (bezt->f2 & SELECT)
- bezt->vec[1][0] = (floorf(bezt->vec[1][0] / secf + 0.5f) * secf);
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->vec[1][0] = (floorf(bezt->vec[1][0] / secf + 0.5f) * secf);
+ return 0;
}
/* snaps the keyframe to the current frame */
static short snap_bezier_cframe(KeyframeEditData *ked, BezTriple *bezt)
{
- const Scene *scene = ked->scene;
- if (bezt->f2 & SELECT)
- bezt->vec[1][0] = (float)CFRA;
- return 0;
+ const Scene *scene = ked->scene;
+ if (bezt->f2 & SELECT)
+ bezt->vec[1][0] = (float)CFRA;
+ return 0;
}
/* snaps the keyframe time to the nearest marker's frame */
static short snap_bezier_nearmarker(KeyframeEditData *ked, BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->vec[1][0] = (float)ED_markers_find_nearest_marker_time(&ked->list, bezt->vec[1][0]);
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->vec[1][0] = (float)ED_markers_find_nearest_marker_time(&ked->list, bezt->vec[1][0]);
+ return 0;
}
/* make the handles have the same value as the key */
static short snap_bezier_horizontal(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT) {
- bezt->vec[0][1] = bezt->vec[2][1] = bezt->vec[1][1];
+ if (bezt->f2 & SELECT) {
+ bezt->vec[0][1] = bezt->vec[2][1] = bezt->vec[1][1];
- if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM, HD_VECT)) bezt->h1 = HD_ALIGN;
- if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM, HD_VECT)) bezt->h2 = HD_ALIGN;
- }
- return 0;
+ if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM, HD_VECT))
+ bezt->h1 = HD_ALIGN;
+ if (ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM, HD_VECT))
+ bezt->h2 = HD_ALIGN;
+ }
+ return 0;
}
/* frame to snap to is stored in the custom data -> first float value slot */
static short snap_bezier_time(KeyframeEditData *ked, BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->vec[1][0] = ked->f1;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->vec[1][0] = ked->f1;
+ return 0;
}
/* value to snap to is stored in the custom data -> first float value slot */
static short snap_bezier_value(KeyframeEditData *ked, BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->vec[1][1] = ked->f1;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->vec[1][1] = ked->f1;
+ return 0;
}
KeyframeEditFunc ANIM_editkeyframes_snap(short type)
{
- /* eEditKeyframes_Snap */
- switch (type) {
- case SNAP_KEYS_NEARFRAME: /* snap to nearest frame */
- return snap_bezier_nearest;
- case SNAP_KEYS_CURFRAME: /* snap to current frame */
- return snap_bezier_cframe;
- case SNAP_KEYS_NEARMARKER: /* snap to nearest marker */
- return snap_bezier_nearmarker;
- case SNAP_KEYS_NEARSEC: /* snap to nearest second */
- return snap_bezier_nearestsec;
- case SNAP_KEYS_HORIZONTAL: /* snap handles to same value */
- return snap_bezier_horizontal;
- case SNAP_KEYS_TIME: /* snap to given frame/time */
- return snap_bezier_time;
- case SNAP_KEYS_VALUE: /* snap to given value */
- return snap_bezier_value;
- default: /* just in case */
- return snap_bezier_nearest;
- }
+ /* eEditKeyframes_Snap */
+ switch (type) {
+ case SNAP_KEYS_NEARFRAME: /* snap to nearest frame */
+ return snap_bezier_nearest;
+ case SNAP_KEYS_CURFRAME: /* snap to current frame */
+ return snap_bezier_cframe;
+ case SNAP_KEYS_NEARMARKER: /* snap to nearest marker */
+ return snap_bezier_nearmarker;
+ case SNAP_KEYS_NEARSEC: /* snap to nearest second */
+ return snap_bezier_nearestsec;
+ case SNAP_KEYS_HORIZONTAL: /* snap handles to same value */
+ return snap_bezier_horizontal;
+ case SNAP_KEYS_TIME: /* snap to given frame/time */
+ return snap_bezier_time;
+ case SNAP_KEYS_VALUE: /* snap to given value */
+ return snap_bezier_value;
+ default: /* just in case */
+ return snap_bezier_nearest;
+ }
}
/* --------- */
static void mirror_bezier_xaxis_ex(BezTriple *bezt, const float center)
{
- float diff;
- int i;
+ float diff;
+ int i;
- for (i = 0; i < 3; i++) {
- diff = (center - bezt->vec[i][0]);
- bezt->vec[i][0] = (center + diff);
- }
- swap_v3_v3(bezt->vec[0], bezt->vec[2]);
+ for (i = 0; i < 3; i++) {
+ diff = (center - bezt->vec[i][0]);
+ bezt->vec[i][0] = (center + diff);
+ }
+ swap_v3_v3(bezt->vec[0], bezt->vec[2]);
- SWAP(char, bezt->h1, bezt->h2);
- SWAP(char, bezt->f1, bezt->f3);
+ SWAP(char, bezt->h1, bezt->h2);
+ SWAP(char, bezt->f1, bezt->f3);
}
static void mirror_bezier_yaxis_ex(BezTriple *bezt, const float center)
{
- float diff;
- int i;
+ float diff;
+ int i;
- for (i = 0; i < 3; i++) {
- diff = (center - bezt->vec[i][1]);
- bezt->vec[i][1] = (center + diff);
- }
+ for (i = 0; i < 3; i++) {
+ diff = (center - bezt->vec[i][1]);
+ bezt->vec[i][1] = (center + diff);
+ }
}
static short mirror_bezier_cframe(KeyframeEditData *ked, BezTriple *bezt)
{
- const Scene *scene = ked->scene;
+ const Scene *scene = ked->scene;
- if (bezt->f2 & SELECT) {
- mirror_bezier_xaxis_ex(bezt, CFRA);
- }
+ if (bezt->f2 & SELECT) {
+ mirror_bezier_xaxis_ex(bezt, CFRA);
+ }
- return 0;
+ return 0;
}
static short mirror_bezier_yaxis(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT) {
- /* Yes, names are inverted, we are mirroring across y axis, hence along x axis... */
- mirror_bezier_xaxis_ex(bezt, 0.0f);
- }
+ if (bezt->f2 & SELECT) {
+ /* Yes, names are inverted, we are mirroring across y axis, hence along x axis... */
+ mirror_bezier_xaxis_ex(bezt, 0.0f);
+ }
- return 0;
+ return 0;
}
static short mirror_bezier_xaxis(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT) {
- /* Yes, names are inverted, we are mirroring across x axis, hence along y axis... */
- mirror_bezier_yaxis_ex(bezt, 0.0f);
- }
+ if (bezt->f2 & SELECT) {
+ /* Yes, names are inverted, we are mirroring across x axis, hence along y axis... */
+ mirror_bezier_yaxis_ex(bezt, 0.0f);
+ }
- return 0;
+ return 0;
}
static short mirror_bezier_marker(KeyframeEditData *ked, BezTriple *bezt)
{
- /* mirroring time stored in f1 */
- if (bezt->f2 & SELECT) {
- mirror_bezier_xaxis_ex(bezt, ked->f1);
- }
+ /* mirroring time stored in f1 */
+ if (bezt->f2 & SELECT) {
+ mirror_bezier_xaxis_ex(bezt, ked->f1);
+ }
- return 0;
+ return 0;
}
static short mirror_bezier_time(KeyframeEditData *ked, BezTriple *bezt)
{
- /* value to mirror over is stored in f1 */
- if (bezt->f2 & SELECT) {
- mirror_bezier_xaxis_ex(bezt, ked->f1);
- }
+ /* value to mirror over is stored in f1 */
+ if (bezt->f2 & SELECT) {
+ mirror_bezier_xaxis_ex(bezt, ked->f1);
+ }
- return 0;
+ return 0;
}
static short mirror_bezier_value(KeyframeEditData *ked, BezTriple *bezt)
{
- /* value to mirror over is stored in the custom data -> first float value slot */
- if (bezt->f2 & SELECT) {
- mirror_bezier_yaxis_ex(bezt, ked->f1);
- }
+ /* value to mirror over is stored in the custom data -> first float value slot */
+ if (bezt->f2 & SELECT) {
+ mirror_bezier_yaxis_ex(bezt, ked->f1);
+ }
- return 0;
+ return 0;
}
/* Note: for markers and 'value', the values to use must be supplied as the first float value */
// calchandles_fcurve
KeyframeEditFunc ANIM_editkeyframes_mirror(short type)
{
- switch (type) {
- case MIRROR_KEYS_CURFRAME: /* mirror over current frame */
- return mirror_bezier_cframe;
- case MIRROR_KEYS_YAXIS: /* mirror over frame 0 */
- return mirror_bezier_yaxis;
- case MIRROR_KEYS_XAXIS: /* mirror over value 0 */
- return mirror_bezier_xaxis;
- case MIRROR_KEYS_MARKER: /* mirror over marker */
- return mirror_bezier_marker;
- case MIRROR_KEYS_TIME: /* mirror over frame/time */
- return mirror_bezier_time;
- case MIRROR_KEYS_VALUE: /* mirror over given value */
- return mirror_bezier_value;
- default: /* just in case */
- return mirror_bezier_yaxis;
- }
+ switch (type) {
+ case MIRROR_KEYS_CURFRAME: /* mirror over current frame */
+ return mirror_bezier_cframe;
+ case MIRROR_KEYS_YAXIS: /* mirror over frame 0 */
+ return mirror_bezier_yaxis;
+ case MIRROR_KEYS_XAXIS: /* mirror over value 0 */
+ return mirror_bezier_xaxis;
+ case MIRROR_KEYS_MARKER: /* mirror over marker */
+ return mirror_bezier_marker;
+ case MIRROR_KEYS_TIME: /* mirror over frame/time */
+ return mirror_bezier_time;
+ case MIRROR_KEYS_VALUE: /* mirror over given value */
+ return mirror_bezier_value;
+ default: /* just in case */
+ return mirror_bezier_yaxis;
+ }
}
/* ******************************************* */
@@ -964,24 +1001,27 @@ KeyframeEditFunc ANIM_editkeyframes_mirror(short type)
/* standard validation step for a few of these (implemented as macro for inlining without fn-call overhead):
* "if the handles are not of the same type, set them to type free"
*/
-#define ENSURE_HANDLES_MATCH(bezt) \
- if (bezt->h1 != bezt->h2) { \
- if (ELEM(bezt->h1, HD_ALIGN, HD_AUTO, HD_AUTO_ANIM)) \
- bezt->h1 = HD_FREE; \
- if (ELEM(bezt->h2, HD_ALIGN, HD_AUTO, HD_AUTO_ANIM)) \
- bezt->h2 = HD_FREE; \
- } (void)0
+#define ENSURE_HANDLES_MATCH(bezt) \
+ if (bezt->h1 != bezt->h2) { \
+ if (ELEM(bezt->h1, HD_ALIGN, HD_AUTO, HD_AUTO_ANIM)) \
+ bezt->h1 = HD_FREE; \
+ if (ELEM(bezt->h2, HD_ALIGN, HD_AUTO, HD_AUTO_ANIM)) \
+ bezt->h2 = HD_FREE; \
+ } \
+ (void)0
/* Sets the selected bezier handles to type 'auto' */
static short set_bezier_auto(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if ((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) {
- if (bezt->f1 & SELECT) bezt->h1 = HD_AUTO;
- if (bezt->f3 & SELECT) bezt->h2 = HD_AUTO;
+ if ((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) {
+ if (bezt->f1 & SELECT)
+ bezt->h1 = HD_AUTO;
+ if (bezt->f3 & SELECT)
+ bezt->h2 = HD_AUTO;
- ENSURE_HANDLES_MATCH(bezt);
- }
- return 0;
+ ENSURE_HANDLES_MATCH(bezt);
+ }
+ return 0;
}
/* Sets the selected bezier handles to type 'auto-clamped'
@@ -989,307 +1029,317 @@ static short set_bezier_auto(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
*/
static short set_bezier_auto_clamped(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if ((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) {
- if (bezt->f1 & SELECT) bezt->h1 = HD_AUTO_ANIM;
- if (bezt->f3 & SELECT) bezt->h2 = HD_AUTO_ANIM;
+ if ((bezt->f1 & SELECT) || (bezt->f3 & SELECT)) {
+ if (bezt->f1 & SELECT)
+ bezt->h1 = HD_AUTO_ANIM;
+ if (bezt->f3 & SELECT)
+ bezt->h2 = HD_AUTO_ANIM;
- ENSURE_HANDLES_MATCH(bezt);
- }
- return 0;
+ ENSURE_HANDLES_MATCH(bezt);
+ }
+ return 0;
}
/* Sets the selected bezier handles to type 'vector' */
static short set_bezier_vector(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f1 & SELECT) bezt->h1 = HD_VECT;
- if (bezt->f3 & SELECT) bezt->h2 = HD_VECT;
- return 0;
+ if (bezt->f1 & SELECT)
+ bezt->h1 = HD_VECT;
+ if (bezt->f3 & SELECT)
+ bezt->h2 = HD_VECT;
+ return 0;
}
/* Queries if the handle should be set to 'free' or 'align' */
// NOTE: this was used for the 'toggle free/align' option
-// currently this isn't used, but may be restored later
+// currently this isn't used, but may be restored later
static short bezier_isfree(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if ((bezt->f1 & SELECT) && (bezt->h1)) return 1;
- if ((bezt->f3 & SELECT) && (bezt->h2)) return 1;
- return 0;
+ if ((bezt->f1 & SELECT) && (bezt->h1))
+ return 1;
+ if ((bezt->f3 & SELECT) && (bezt->h2))
+ return 1;
+ return 0;
}
/* Sets selected bezier handles to type 'align' */
static short set_bezier_align(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f1 & SELECT) bezt->h1 = HD_ALIGN;
- if (bezt->f3 & SELECT) bezt->h2 = HD_ALIGN;
- return 0;
+ if (bezt->f1 & SELECT)
+ bezt->h1 = HD_ALIGN;
+ if (bezt->f3 & SELECT)
+ bezt->h2 = HD_ALIGN;
+ return 0;
}
/* Sets selected bezier handles to type 'free' */
static short set_bezier_free(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f1 & SELECT) bezt->h1 = HD_FREE;
- if (bezt->f3 & SELECT) bezt->h2 = HD_FREE;
- return 0;
+ if (bezt->f1 & SELECT)
+ bezt->h1 = HD_FREE;
+ if (bezt->f3 & SELECT)
+ bezt->h2 = HD_FREE;
+ return 0;
}
/* Set all selected Bezier Handles to a single type */
// calchandles_fcurve
KeyframeEditFunc ANIM_editkeyframes_handles(short code)
{
- switch (code) {
- case HD_AUTO: /* auto */
- return set_bezier_auto;
- case HD_AUTO_ANIM: /* auto clamped */
- return set_bezier_auto_clamped;
+ switch (code) {
+ case HD_AUTO: /* auto */
+ return set_bezier_auto;
+ case HD_AUTO_ANIM: /* auto clamped */
+ return set_bezier_auto_clamped;
- case HD_VECT: /* vector */
- return set_bezier_vector;
- case HD_FREE: /* free */
- return set_bezier_free;
- case HD_ALIGN: /* align */
- return set_bezier_align;
+ case HD_VECT: /* vector */
+ return set_bezier_vector;
+ case HD_FREE: /* free */
+ return set_bezier_free;
+ case HD_ALIGN: /* align */
+ return set_bezier_align;
- default: /* check for toggle free or align? */
- return bezier_isfree;
- }
+ default: /* check for toggle free or align? */
+ return bezier_isfree;
+ }
}
/* ------- */
static short set_bezt_constant(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->ipo = BEZT_IPO_CONST;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_CONST;
+ return 0;
}
static short set_bezt_linear(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->ipo = BEZT_IPO_LIN;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_LIN;
+ return 0;
}
static short set_bezt_bezier(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->ipo = BEZT_IPO_BEZ;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_BEZ;
+ return 0;
}
static short set_bezt_back(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->ipo = BEZT_IPO_BACK;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_BACK;
+ return 0;
}
static short set_bezt_bounce(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->ipo = BEZT_IPO_BOUNCE;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_BOUNCE;
+ return 0;
}
static short set_bezt_circle(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->ipo = BEZT_IPO_CIRC;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_CIRC;
+ return 0;
}
static short set_bezt_cubic(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->ipo = BEZT_IPO_CUBIC;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_CUBIC;
+ return 0;
}
static short set_bezt_elastic(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->ipo = BEZT_IPO_ELASTIC;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_ELASTIC;
+ return 0;
}
static short set_bezt_expo(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->ipo = BEZT_IPO_EXPO;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_EXPO;
+ return 0;
}
static short set_bezt_quad(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->ipo = BEZT_IPO_QUAD;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_QUAD;
+ return 0;
}
static short set_bezt_quart(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->ipo = BEZT_IPO_QUART;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_QUART;
+ return 0;
}
static short set_bezt_quint(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->ipo = BEZT_IPO_QUINT;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_QUINT;
+ return 0;
}
static short set_bezt_sine(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->ipo = BEZT_IPO_SINE;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->ipo = BEZT_IPO_SINE;
+ return 0;
}
/* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */
// ANIM_editkeyframes_ipocurve_ipotype() !
KeyframeEditFunc ANIM_editkeyframes_ipo(short code)
{
- switch (code) {
- /* interpolation */
- case BEZT_IPO_CONST: /* constant */
- return set_bezt_constant;
- case BEZT_IPO_LIN: /* linear */
- return set_bezt_linear;
-
- /* easing */
- case BEZT_IPO_BACK:
- return set_bezt_back;
- case BEZT_IPO_BOUNCE:
- return set_bezt_bounce;
- case BEZT_IPO_CIRC:
- return set_bezt_circle;
- case BEZT_IPO_CUBIC:
- return set_bezt_cubic;
- case BEZT_IPO_ELASTIC:
- return set_bezt_elastic;
- case BEZT_IPO_EXPO:
- return set_bezt_expo;
- case BEZT_IPO_QUAD:
- return set_bezt_quad;
- case BEZT_IPO_QUART:
- return set_bezt_quart;
- case BEZT_IPO_QUINT:
- return set_bezt_quint;
- case BEZT_IPO_SINE:
- return set_bezt_sine;
-
- default: /* bezier */
- return set_bezt_bezier;
- }
+ switch (code) {
+ /* interpolation */
+ case BEZT_IPO_CONST: /* constant */
+ return set_bezt_constant;
+ case BEZT_IPO_LIN: /* linear */
+ return set_bezt_linear;
+
+ /* easing */
+ case BEZT_IPO_BACK:
+ return set_bezt_back;
+ case BEZT_IPO_BOUNCE:
+ return set_bezt_bounce;
+ case BEZT_IPO_CIRC:
+ return set_bezt_circle;
+ case BEZT_IPO_CUBIC:
+ return set_bezt_cubic;
+ case BEZT_IPO_ELASTIC:
+ return set_bezt_elastic;
+ case BEZT_IPO_EXPO:
+ return set_bezt_expo;
+ case BEZT_IPO_QUAD:
+ return set_bezt_quad;
+ case BEZT_IPO_QUART:
+ return set_bezt_quart;
+ case BEZT_IPO_QUINT:
+ return set_bezt_quint;
+ case BEZT_IPO_SINE:
+ return set_bezt_sine;
+
+ default: /* bezier */
+ return set_bezt_bezier;
+ }
}
/* ------- */
static short set_keytype_keyframe(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- BEZKEYTYPE(bezt) = BEZT_KEYTYPE_KEYFRAME;
- return 0;
+ if (bezt->f2 & SELECT)
+ BEZKEYTYPE(bezt) = BEZT_KEYTYPE_KEYFRAME;
+ return 0;
}
static short set_keytype_breakdown(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- BEZKEYTYPE(bezt) = BEZT_KEYTYPE_BREAKDOWN;
- return 0;
+ if (bezt->f2 & SELECT)
+ BEZKEYTYPE(bezt) = BEZT_KEYTYPE_BREAKDOWN;
+ return 0;
}
static short set_keytype_extreme(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- BEZKEYTYPE(bezt) = BEZT_KEYTYPE_EXTREME;
- return 0;
+ if (bezt->f2 & SELECT)
+ BEZKEYTYPE(bezt) = BEZT_KEYTYPE_EXTREME;
+ return 0;
}
static short set_keytype_jitter(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- BEZKEYTYPE(bezt) = BEZT_KEYTYPE_JITTER;
- return 0;
+ if (bezt->f2 & SELECT)
+ BEZKEYTYPE(bezt) = BEZT_KEYTYPE_JITTER;
+ return 0;
}
static short set_keytype_moving_hold(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- BEZKEYTYPE(bezt) = BEZT_KEYTYPE_MOVEHOLD;
- return 0;
+ if (bezt->f2 & SELECT)
+ BEZKEYTYPE(bezt) = BEZT_KEYTYPE_MOVEHOLD;
+ return 0;
}
/* Set the interpolation type of the selected BezTriples in each F-Curve to the specified one */
KeyframeEditFunc ANIM_editkeyframes_keytype(short code)
{
- switch (code) {
- case BEZT_KEYTYPE_BREAKDOWN: /* breakdown */
- return set_keytype_breakdown;
+ switch (code) {
+ case BEZT_KEYTYPE_BREAKDOWN: /* breakdown */
+ return set_keytype_breakdown;
- case BEZT_KEYTYPE_EXTREME: /* extreme keyframe */
- return set_keytype_extreme;
+ case BEZT_KEYTYPE_EXTREME: /* extreme keyframe */
+ return set_keytype_extreme;
- case BEZT_KEYTYPE_JITTER: /* jitter keyframe */
- return set_keytype_jitter;
+ case BEZT_KEYTYPE_JITTER: /* jitter keyframe */
+ return set_keytype_jitter;
- case BEZT_KEYTYPE_MOVEHOLD: /* moving hold */
- return set_keytype_moving_hold;
+ case BEZT_KEYTYPE_MOVEHOLD: /* moving hold */
+ return set_keytype_moving_hold;
- case BEZT_KEYTYPE_KEYFRAME: /* proper keyframe */
- default:
- return set_keytype_keyframe;
- }
+ case BEZT_KEYTYPE_KEYFRAME: /* proper keyframe */
+ default:
+ return set_keytype_keyframe;
+ }
}
/* ------- */
static short set_easingtype_easein(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->easing = BEZT_IPO_EASE_IN;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->easing = BEZT_IPO_EASE_IN;
+ return 0;
}
static short set_easingtype_easeout(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->easing = BEZT_IPO_EASE_OUT;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->easing = BEZT_IPO_EASE_OUT;
+ return 0;
}
static short set_easingtype_easeinout(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->easing = BEZT_IPO_EASE_IN_OUT;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->easing = BEZT_IPO_EASE_IN_OUT;
+ return 0;
}
static short set_easingtype_easeauto(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- if (bezt->f2 & SELECT)
- bezt->easing = BEZT_IPO_EASE_AUTO;
- return 0;
+ if (bezt->f2 & SELECT)
+ bezt->easing = BEZT_IPO_EASE_AUTO;
+ return 0;
}
/* Set the easing type of the selected BezTriples in each F-Curve to the specified one */
KeyframeEditFunc ANIM_editkeyframes_easing(short mode)
{
- switch (mode) {
- case BEZT_IPO_EASE_IN: /* ease in */
- return set_easingtype_easein;
+ switch (mode) {
+ case BEZT_IPO_EASE_IN: /* ease in */
+ return set_easingtype_easein;
- case BEZT_IPO_EASE_OUT: /* ease out */
- return set_easingtype_easeout;
+ case BEZT_IPO_EASE_OUT: /* ease out */
+ return set_easingtype_easeout;
- case BEZT_IPO_EASE_IN_OUT: /* both */
- return set_easingtype_easeinout;
+ case BEZT_IPO_EASE_IN_OUT: /* both */
+ return set_easingtype_easeinout;
- default: /* auto */
- return set_easingtype_easeauto;
- }
+ default: /* auto */
+ return set_easingtype_easeauto;
+ }
}
/* ******************************************* */
@@ -1297,67 +1347,67 @@ KeyframeEditFunc ANIM_editkeyframes_easing(short mode)
static short select_bezier_add(KeyframeEditData *ked, BezTriple *bezt)
{
- /* if we've got info on what to select, use it, otherwise select all */
- if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) {
- if (ked->curflags & KEYFRAME_OK_KEY)
- bezt->f2 |= SELECT;
- if (ked->curflags & KEYFRAME_OK_H1)
- bezt->f1 |= SELECT;
- if (ked->curflags & KEYFRAME_OK_H2)
- bezt->f3 |= SELECT;
- }
- else {
- BEZT_SEL_ALL(bezt);
- }
+ /* if we've got info on what to select, use it, otherwise select all */
+ if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) {
+ if (ked->curflags & KEYFRAME_OK_KEY)
+ bezt->f2 |= SELECT;
+ if (ked->curflags & KEYFRAME_OK_H1)
+ bezt->f1 |= SELECT;
+ if (ked->curflags & KEYFRAME_OK_H2)
+ bezt->f3 |= SELECT;
+ }
+ else {
+ BEZT_SEL_ALL(bezt);
+ }
- return 0;
+ return 0;
}
static short select_bezier_subtract(KeyframeEditData *ked, BezTriple *bezt)
{
- /* if we've got info on what to deselect, use it, otherwise deselect all */
- if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) {
- if (ked->curflags & KEYFRAME_OK_KEY)
- bezt->f2 &= ~SELECT;
- if (ked->curflags & KEYFRAME_OK_H1)
- bezt->f1 &= ~SELECT;
- if (ked->curflags & KEYFRAME_OK_H2)
- bezt->f3 &= ~SELECT;
- }
- else {
- BEZT_DESEL_ALL(bezt);
- }
+ /* if we've got info on what to deselect, use it, otherwise deselect all */
+ if ((ked) && (ked->iterflags & KEYFRAME_ITER_INCL_HANDLES)) {
+ if (ked->curflags & KEYFRAME_OK_KEY)
+ bezt->f2 &= ~SELECT;
+ if (ked->curflags & KEYFRAME_OK_H1)
+ bezt->f1 &= ~SELECT;
+ if (ked->curflags & KEYFRAME_OK_H2)
+ bezt->f3 &= ~SELECT;
+ }
+ else {
+ BEZT_DESEL_ALL(bezt);
+ }
- return 0;
+ return 0;
}
static short select_bezier_invert(KeyframeEditData *UNUSED(ked), BezTriple *bezt)
{
- /* Invert the selection for the whole bezier triple */
- bezt->f2 ^= SELECT;
- if (bezt->f2 & SELECT) {
- bezt->f1 |= SELECT;
- bezt->f3 |= SELECT;
- }
- else {
- bezt->f1 &= ~SELECT;
- bezt->f3 &= ~SELECT;
- }
- return 0;
+ /* Invert the selection for the whole bezier triple */
+ bezt->f2 ^= SELECT;
+ if (bezt->f2 & SELECT) {
+ bezt->f1 |= SELECT;
+ bezt->f3 |= SELECT;
+ }
+ else {
+ bezt->f1 &= ~SELECT;
+ bezt->f3 &= ~SELECT;
+ }
+ return 0;
}
KeyframeEditFunc ANIM_editkeyframes_select(short selectmode)
{
- switch (selectmode) {
- case SELECT_ADD: /* add */
- return select_bezier_add;
- case SELECT_SUBTRACT: /* subtract */
- return select_bezier_subtract;
- case SELECT_INVERT: /* invert */
- return select_bezier_invert;
- default: /* replace (need to clear all, then add) */
- return select_bezier_add;
- }
+ switch (selectmode) {
+ case SELECT_ADD: /* add */
+ return select_bezier_add;
+ case SELECT_SUBTRACT: /* subtract */
+ return select_bezier_subtract;
+ case SELECT_INVERT: /* invert */
+ return select_bezier_invert;
+ default: /* replace (need to clear all, then add) */
+ return select_bezier_add;
+ }
}
/* ******************************************* */
@@ -1373,91 +1423,91 @@ KeyframeEditFunc ANIM_editkeyframes_select(short selectmode)
static short selmap_build_bezier_more(KeyframeEditData *ked, BezTriple *bezt)
{
- FCurve *fcu = ked->fcu;
- char *map = ked->data;
- int i = ked->curIndex;
+ FCurve *fcu = ked->fcu;
+ char *map = ked->data;
+ int i = ked->curIndex;
- /* if current is selected, just make sure it stays this way */
- if (BEZT_ISSEL_ANY(bezt)) {
- map[i] = 1;
- return 0;
- }
+ /* if current is selected, just make sure it stays this way */
+ if (BEZT_ISSEL_ANY(bezt)) {
+ map[i] = 1;
+ return 0;
+ }
- /* if previous is selected, that means that selection should extend across */
- if (i > 0) {
- BezTriple *prev = bezt - 1;
+ /* if previous is selected, that means that selection should extend across */
+ if (i > 0) {
+ BezTriple *prev = bezt - 1;
- if (BEZT_ISSEL_ANY(prev)) {
- map[i] = 1;
- return 0;
- }
- }
+ if (BEZT_ISSEL_ANY(prev)) {
+ map[i] = 1;
+ return 0;
+ }
+ }
- /* if next is selected, that means that selection should extend across */
- if (i < (fcu->totvert - 1)) {
- BezTriple *next = bezt + 1;
+ /* if next is selected, that means that selection should extend across */
+ if (i < (fcu->totvert - 1)) {
+ BezTriple *next = bezt + 1;
- if (BEZT_ISSEL_ANY(next)) {
- map[i] = 1;
- return 0;
- }
- }
+ if (BEZT_ISSEL_ANY(next)) {
+ map[i] = 1;
+ return 0;
+ }
+ }
- return 0;
+ return 0;
}
static short selmap_build_bezier_less(KeyframeEditData *ked, BezTriple *bezt)
{
- FCurve *fcu = ked->fcu;
- char *map = ked->data;
- int i = ked->curIndex;
-
- /* if current is selected, check the left/right keyframes
- * since it might need to be deselected (but otherwise no)
- */
- if (BEZT_ISSEL_ANY(bezt)) {
- /* if previous is not selected, we're on the tip of an iceberg */
- if (i > 0) {
- BezTriple *prev = bezt - 1;
-
- if (BEZT_ISSEL_ANY(prev) == 0)
- return 0;
- }
- else if (i == 0) {
- /* current keyframe is selected at an endpoint, so should get deselected */
- return 0;
- }
-
- /* if next is not selected, we're on the tip of an iceberg */
- if (i < (fcu->totvert - 1)) {
- BezTriple *next = bezt + 1;
-
- if (BEZT_ISSEL_ANY(next) == 0)
- return 0;
- }
- else if (i == (fcu->totvert - 1)) {
- /* current keyframe is selected at an endpoint, so should get deselected */
- return 0;
- }
-
- /* if we're still here, that means that keyframe should remain untouched */
- map[i] = 1;
- }
-
- return 0;
+ FCurve *fcu = ked->fcu;
+ char *map = ked->data;
+ int i = ked->curIndex;
+
+ /* if current is selected, check the left/right keyframes
+ * since it might need to be deselected (but otherwise no)
+ */
+ if (BEZT_ISSEL_ANY(bezt)) {
+ /* if previous is not selected, we're on the tip of an iceberg */
+ if (i > 0) {
+ BezTriple *prev = bezt - 1;
+
+ if (BEZT_ISSEL_ANY(prev) == 0)
+ return 0;
+ }
+ else if (i == 0) {
+ /* current keyframe is selected at an endpoint, so should get deselected */
+ return 0;
+ }
+
+ /* if next is not selected, we're on the tip of an iceberg */
+ if (i < (fcu->totvert - 1)) {
+ BezTriple *next = bezt + 1;
+
+ if (BEZT_ISSEL_ANY(next) == 0)
+ return 0;
+ }
+ else if (i == (fcu->totvert - 1)) {
+ /* current keyframe is selected at an endpoint, so should get deselected */
+ return 0;
+ }
+
+ /* if we're still here, that means that keyframe should remain untouched */
+ map[i] = 1;
+ }
+
+ return 0;
}
/* Get callback for building selection map */
KeyframeEditFunc ANIM_editkeyframes_buildselmap(short mode)
{
- switch (mode) {
- case SELMAP_LESS: /* less */
- return selmap_build_bezier_less;
+ switch (mode) {
+ case SELMAP_LESS: /* less */
+ return selmap_build_bezier_less;
- case SELMAP_MORE: /* more */
- default:
- return selmap_build_bezier_more;
- }
+ case SELMAP_MORE: /* more */
+ default:
+ return selmap_build_bezier_more;
+ }
}
/* ----------- */
@@ -1465,16 +1515,16 @@ KeyframeEditFunc ANIM_editkeyframes_buildselmap(short mode)
/* flush selection map values to the given beztriple */
short bezt_selmap_flush(KeyframeEditData *ked, BezTriple *bezt)
{
- const char *map = ked->data;
- short on = map[ked->curIndex];
+ const char *map = ked->data;
+ short on = map[ked->curIndex];
- /* select or deselect based on whether the map allows it or not */
- if (on) {
- BEZT_SEL_ALL(bezt);
- }
- else {
- BEZT_DESEL_ALL(bezt);
- }
+ /* select or deselect based on whether the map allows it or not */
+ if (on) {
+ BEZT_SEL_ALL(bezt);
+ }
+ else {
+ BEZT_DESEL_ALL(bezt);
+ }
- return 0;
+ return 0;
}
diff --git a/source/blender/editors/animation/keyframes_general.c b/source/blender/editors/animation/keyframes_general.c
index c9e672a111d..945327ed78b 100644
--- a/source/blender/editors/animation/keyframes_general.c
+++ b/source/blender/editors/animation/keyframes_general.c
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
#include <stdlib.h>
#include <string.h>
#include <math.h>
@@ -37,7 +36,6 @@
#include "DNA_object_types.h"
#include "DNA_scene_types.h"
-
#include "BKE_action.h"
#include "BKE_fcurve.h"
#include "BKE_report.h"
@@ -71,68 +69,68 @@
*/
void delete_fcurve_key(FCurve *fcu, int index, bool do_recalc)
{
- /* sanity check */
- if (fcu == NULL)
- return;
-
- /* verify the index:
- * 1) cannot be greater than the number of available keyframes
- * 2) negative indices are for specifying a value from the end of the array
- */
- if (abs(index) >= fcu->totvert)
- return;
- else if (index < 0)
- index += fcu->totvert;
-
- /* Delete this keyframe */
- memmove(&fcu->bezt[index], &fcu->bezt[index + 1], sizeof(BezTriple) * (fcu->totvert - index - 1));
- fcu->totvert--;
-
- if (fcu->totvert == 0) {
- if (fcu->bezt)
- MEM_freeN(fcu->bezt);
- fcu->bezt = NULL;
- }
-
- /* recalc handles - only if it won't cause problems */
- if (do_recalc)
- calchandles_fcurve(fcu);
+ /* sanity check */
+ if (fcu == NULL)
+ return;
+
+ /* verify the index:
+ * 1) cannot be greater than the number of available keyframes
+ * 2) negative indices are for specifying a value from the end of the array
+ */
+ if (abs(index) >= fcu->totvert)
+ return;
+ else if (index < 0)
+ index += fcu->totvert;
+
+ /* Delete this keyframe */
+ memmove(
+ &fcu->bezt[index], &fcu->bezt[index + 1], sizeof(BezTriple) * (fcu->totvert - index - 1));
+ fcu->totvert--;
+
+ if (fcu->totvert == 0) {
+ if (fcu->bezt)
+ MEM_freeN(fcu->bezt);
+ fcu->bezt = NULL;
+ }
+
+ /* recalc handles - only if it won't cause problems */
+ if (do_recalc)
+ calchandles_fcurve(fcu);
}
/* Delete selected keyframes in given F-Curve */
bool delete_fcurve_keys(FCurve *fcu)
{
- int i;
- bool changed = false;
-
- if (fcu->bezt == NULL) /* ignore baked curves */
- return false;
-
- /* Delete selected BezTriples */
- for (i = 0; i < fcu->totvert; i++) {
- if (fcu->bezt[i].f2 & SELECT) {
- memmove(&fcu->bezt[i], &fcu->bezt[i + 1], sizeof(BezTriple) * (fcu->totvert - i - 1));
- fcu->totvert--;
- i--;
- changed = true;
- }
- }
-
- /* Free the array of BezTriples if there are not keyframes */
- if (fcu->totvert == 0)
- clear_fcurve_keys(fcu);
-
- return changed;
+ int i;
+ bool changed = false;
+
+ if (fcu->bezt == NULL) /* ignore baked curves */
+ return false;
+
+ /* Delete selected BezTriples */
+ for (i = 0; i < fcu->totvert; i++) {
+ if (fcu->bezt[i].f2 & SELECT) {
+ memmove(&fcu->bezt[i], &fcu->bezt[i + 1], sizeof(BezTriple) * (fcu->totvert - i - 1));
+ fcu->totvert--;
+ i--;
+ changed = true;
+ }
+ }
+
+ /* Free the array of BezTriples if there are not keyframes */
+ if (fcu->totvert == 0)
+ clear_fcurve_keys(fcu);
+
+ return changed;
}
-
void clear_fcurve_keys(FCurve *fcu)
{
- if (fcu->bezt)
- MEM_freeN(fcu->bezt);
- fcu->bezt = NULL;
+ if (fcu->bezt)
+ MEM_freeN(fcu->bezt);
+ fcu->bezt = NULL;
- fcu->totvert = 0;
+ fcu->totvert = 0;
}
/* ---------------- */
@@ -140,36 +138,36 @@ void clear_fcurve_keys(FCurve *fcu)
/* duplicate selected keyframes for the given F-Curve */
void duplicate_fcurve_keys(FCurve *fcu)
{
- BezTriple *newbezt;
- int i;
-
- /* this can only work when there is an F-Curve, and also when there are some BezTriples */
- if (ELEM(NULL, fcu, fcu->bezt))
- return;
-
- for (i = 0; i < fcu->totvert; i++) {
- /* If a key is selected */
- if (fcu->bezt[i].f2 & SELECT) {
- /* Expand the list */
- newbezt = MEM_callocN(sizeof(BezTriple) * (fcu->totvert + 1), "beztriple");
-
- memcpy(newbezt, fcu->bezt, sizeof(BezTriple) * (i + 1));
- memcpy(newbezt + i + 1, fcu->bezt + i, sizeof(BezTriple));
- memcpy(newbezt + i + 2, fcu->bezt + i + 1, sizeof(BezTriple) * (fcu->totvert - (i + 1)));
- fcu->totvert++;
-
- /* reassign pointers... (free old, and add new) */
- MEM_freeN(fcu->bezt);
- fcu->bezt = newbezt;
-
- /* Unselect the current key */
- BEZT_DESEL_ALL(&fcu->bezt[i]);
- i++;
-
- /* Select the copied key */
- BEZT_SEL_ALL(&fcu->bezt[i]);
- }
- }
+ BezTriple *newbezt;
+ int i;
+
+ /* this can only work when there is an F-Curve, and also when there are some BezTriples */
+ if (ELEM(NULL, fcu, fcu->bezt))
+ return;
+
+ for (i = 0; i < fcu->totvert; i++) {
+ /* If a key is selected */
+ if (fcu->bezt[i].f2 & SELECT) {
+ /* Expand the list */
+ newbezt = MEM_callocN(sizeof(BezTriple) * (fcu->totvert + 1), "beztriple");
+
+ memcpy(newbezt, fcu->bezt, sizeof(BezTriple) * (i + 1));
+ memcpy(newbezt + i + 1, fcu->bezt + i, sizeof(BezTriple));
+ memcpy(newbezt + i + 2, fcu->bezt + i + 1, sizeof(BezTriple) * (fcu->totvert - (i + 1)));
+ fcu->totvert++;
+
+ /* reassign pointers... (free old, and add new) */
+ MEM_freeN(fcu->bezt);
+ fcu->bezt = newbezt;
+
+ /* Unselect the current key */
+ BEZT_DESEL_ALL(&fcu->bezt[i]);
+ i++;
+
+ /* Select the copied key */
+ BEZT_SEL_ALL(&fcu->bezt[i]);
+ }
+ }
}
/* **************************************************** */
@@ -180,327 +178,325 @@ void duplicate_fcurve_keys(FCurve *fcu)
*/
void clean_fcurve(struct bAnimContext *ac, bAnimListElem *ale, float thresh, bool cleardefault)
{
- FCurve *fcu = (FCurve *)ale->key_data;
- BezTriple *old_bezts, *bezt, *beztn;
- BezTriple *lastb;
- int totCount, i;
-
- /* check if any points */
- if ((fcu == NULL) || (fcu->bezt == NULL) || (fcu->totvert == 0) ||
- (!cleardefault && fcu->totvert == 1))
- {
- return;
- }
-
- /* make a copy of the old BezTriples, and clear F-Curve */
- old_bezts = fcu->bezt;
- totCount = fcu->totvert;
- fcu->bezt = NULL;
- fcu->totvert = 0;
-
- /* now insert first keyframe, as it should be ok */
- bezt = old_bezts;
- insert_bezt_fcurve(fcu, bezt, 0);
- if (!(bezt->f2 & SELECT)) {
- lastb = fcu->bezt;
- lastb->f1 = lastb->f2 = lastb->f3 = 0;
- }
-
- /* Loop through BezTriples, comparing them. Skip any that do
- * not fit the criteria for "ok" points.
- */
- for (i = 1; i < totCount; i++) {
- float prev[2], cur[2], next[2];
-
- /* get BezTriples and their values */
- if (i < (totCount - 1)) {
- beztn = (old_bezts + (i + 1));
- next[0] = beztn->vec[1][0]; next[1] = beztn->vec[1][1];
- }
- else {
- beztn = NULL;
- next[0] = next[1] = 0.0f;
- }
- lastb = (fcu->bezt + (fcu->totvert - 1));
- bezt = (old_bezts + i);
-
- /* get references for quicker access */
- prev[0] = lastb->vec[1][0]; prev[1] = lastb->vec[1][1];
- cur[0] = bezt->vec[1][0]; cur[1] = bezt->vec[1][1];
-
- if (!(bezt->f2 & SELECT)) {
- insert_bezt_fcurve(fcu, bezt, 0);
- lastb = (fcu->bezt + (fcu->totvert - 1));
- lastb->f1 = lastb->f2 = lastb->f3 = 0;
- continue;
- }
-
- /* check if current bezt occurs at same time as last ok */
- if (IS_EQT(cur[0], prev[0], thresh)) {
- /* If there is a next beztriple, and if occurs at the same time, only insert
- * if there is a considerable distance between the points, and also if the
- * current is further away than the next one is to the previous.
- */
- if (beztn && (IS_EQT(cur[0], next[0], thresh)) &&
- (IS_EQT(next[1], prev[1], thresh) == 0))
- {
- /* only add if current is further away from previous */
- if (cur[1] > next[1]) {
- if (IS_EQT(cur[1], prev[1], thresh) == 0) {
- /* add new keyframe */
- insert_bezt_fcurve(fcu, bezt, 0);
- }
- }
- }
- else {
- /* only add if values are a considerable distance apart */
- if (IS_EQT(cur[1], prev[1], thresh) == 0) {
- /* add new keyframe */
- insert_bezt_fcurve(fcu, bezt, 0);
- }
- }
- }
- else {
- /* checks required are dependent on whether this is last keyframe or not */
- if (beztn) {
- /* does current have same value as previous and next? */
- if (IS_EQT(cur[1], prev[1], thresh) == 0) {
- /* add new keyframe */
- insert_bezt_fcurve(fcu, bezt, 0);
- }
- else if (IS_EQT(cur[1], next[1], thresh) == 0) {
- /* add new keyframe */
- insert_bezt_fcurve(fcu, bezt, 0);
- }
- }
- else {
- /* add if value doesn't equal that of previous */
- if (IS_EQT(cur[1], prev[1], thresh) == 0) {
- /* add new keyframe */
- insert_bezt_fcurve(fcu, bezt, 0);
- }
- }
- }
- }
-
- /* now free the memory used by the old BezTriples */
- if (old_bezts)
- MEM_freeN(old_bezts);
-
- /* final step, if there is just one key in fcurve, check if it's
- * the default value and if is, remove fcurve completely. */
- if (cleardefault && fcu->totvert == 1) {
- float default_value = 0.0f;
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
- RNA_id_pointer_create(ale->id, &id_ptr);
-
- /* get property to read from, and get value as appropriate */
- if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
- if (RNA_property_type(prop) == PROP_FLOAT)
- default_value = RNA_property_float_get_default_index(&ptr, prop, fcu->array_index);
- }
-
- if (fcu->bezt->vec[1][1] == default_value) {
- clear_fcurve_keys(fcu);
-
- /* check if curve is really unused and if it is, return signal for deletion */
- if ((list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0) &&
- (fcu->driver == NULL))
- {
- AnimData *adt = ale->adt;
- ANIM_fcurve_delete_from_animdata(ac, adt, fcu);
- ale->key_data = NULL;
- }
- }
- }
+ FCurve *fcu = (FCurve *)ale->key_data;
+ BezTriple *old_bezts, *bezt, *beztn;
+ BezTriple *lastb;
+ int totCount, i;
+
+ /* check if any points */
+ if ((fcu == NULL) || (fcu->bezt == NULL) || (fcu->totvert == 0) ||
+ (!cleardefault && fcu->totvert == 1)) {
+ return;
+ }
+
+ /* make a copy of the old BezTriples, and clear F-Curve */
+ old_bezts = fcu->bezt;
+ totCount = fcu->totvert;
+ fcu->bezt = NULL;
+ fcu->totvert = 0;
+
+ /* now insert first keyframe, as it should be ok */
+ bezt = old_bezts;
+ insert_bezt_fcurve(fcu, bezt, 0);
+ if (!(bezt->f2 & SELECT)) {
+ lastb = fcu->bezt;
+ lastb->f1 = lastb->f2 = lastb->f3 = 0;
+ }
+
+ /* Loop through BezTriples, comparing them. Skip any that do
+ * not fit the criteria for "ok" points.
+ */
+ for (i = 1; i < totCount; i++) {
+ float prev[2], cur[2], next[2];
+
+ /* get BezTriples and their values */
+ if (i < (totCount - 1)) {
+ beztn = (old_bezts + (i + 1));
+ next[0] = beztn->vec[1][0];
+ next[1] = beztn->vec[1][1];
+ }
+ else {
+ beztn = NULL;
+ next[0] = next[1] = 0.0f;
+ }
+ lastb = (fcu->bezt + (fcu->totvert - 1));
+ bezt = (old_bezts + i);
+
+ /* get references for quicker access */
+ prev[0] = lastb->vec[1][0];
+ prev[1] = lastb->vec[1][1];
+ cur[0] = bezt->vec[1][0];
+ cur[1] = bezt->vec[1][1];
+
+ if (!(bezt->f2 & SELECT)) {
+ insert_bezt_fcurve(fcu, bezt, 0);
+ lastb = (fcu->bezt + (fcu->totvert - 1));
+ lastb->f1 = lastb->f2 = lastb->f3 = 0;
+ continue;
+ }
+
+ /* check if current bezt occurs at same time as last ok */
+ if (IS_EQT(cur[0], prev[0], thresh)) {
+ /* If there is a next beztriple, and if occurs at the same time, only insert
+ * if there is a considerable distance between the points, and also if the
+ * current is further away than the next one is to the previous.
+ */
+ if (beztn && (IS_EQT(cur[0], next[0], thresh)) && (IS_EQT(next[1], prev[1], thresh) == 0)) {
+ /* only add if current is further away from previous */
+ if (cur[1] > next[1]) {
+ if (IS_EQT(cur[1], prev[1], thresh) == 0) {
+ /* add new keyframe */
+ insert_bezt_fcurve(fcu, bezt, 0);
+ }
+ }
+ }
+ else {
+ /* only add if values are a considerable distance apart */
+ if (IS_EQT(cur[1], prev[1], thresh) == 0) {
+ /* add new keyframe */
+ insert_bezt_fcurve(fcu, bezt, 0);
+ }
+ }
+ }
+ else {
+ /* checks required are dependent on whether this is last keyframe or not */
+ if (beztn) {
+ /* does current have same value as previous and next? */
+ if (IS_EQT(cur[1], prev[1], thresh) == 0) {
+ /* add new keyframe */
+ insert_bezt_fcurve(fcu, bezt, 0);
+ }
+ else if (IS_EQT(cur[1], next[1], thresh) == 0) {
+ /* add new keyframe */
+ insert_bezt_fcurve(fcu, bezt, 0);
+ }
+ }
+ else {
+ /* add if value doesn't equal that of previous */
+ if (IS_EQT(cur[1], prev[1], thresh) == 0) {
+ /* add new keyframe */
+ insert_bezt_fcurve(fcu, bezt, 0);
+ }
+ }
+ }
+ }
+
+ /* now free the memory used by the old BezTriples */
+ if (old_bezts)
+ MEM_freeN(old_bezts);
+
+ /* final step, if there is just one key in fcurve, check if it's
+ * the default value and if is, remove fcurve completely. */
+ if (cleardefault && fcu->totvert == 1) {
+ float default_value = 0.0f;
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ RNA_id_pointer_create(ale->id, &id_ptr);
+
+ /* get property to read from, and get value as appropriate */
+ if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &ptr, &prop)) {
+ if (RNA_property_type(prop) == PROP_FLOAT)
+ default_value = RNA_property_float_get_default_index(&ptr, prop, fcu->array_index);
+ }
+
+ if (fcu->bezt->vec[1][1] == default_value) {
+ clear_fcurve_keys(fcu);
+
+ /* check if curve is really unused and if it is, return signal for deletion */
+ if ((list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0) &&
+ (fcu->driver == NULL)) {
+ AnimData *adt = ale->adt;
+ ANIM_fcurve_delete_from_animdata(ac, adt, fcu);
+ ale->key_data = NULL;
+ }
+ }
+ }
}
/* ---------------- */
/* temp struct used for smooth_fcurve */
typedef struct tSmooth_Bezt {
- float *h1, *h2, *h3; /* bezt->vec[0,1,2][1] */
- float y1, y2, y3; /* averaged before/new/after y-values */
+ float *h1, *h2, *h3; /* bezt->vec[0,1,2][1] */
+ float y1, y2, y3; /* averaged before/new/after y-values */
} tSmooth_Bezt;
/* Use a weighted moving-means method to reduce intensity of fluctuations */
// TODO: introduce scaling factor for weighting falloff
void smooth_fcurve(FCurve *fcu)
{
- BezTriple *bezt;
- int i, x, totSel = 0;
-
- if (fcu->bezt == NULL) {
- return;
- }
-
- /* first loop through - count how many verts are selected */
- bezt = fcu->bezt;
- for (i = 0; i < fcu->totvert; i++, bezt++) {
- if (BEZT_ISSEL_ANY(bezt))
- totSel++;
- }
-
- /* if any points were selected, allocate tSmooth_Bezt points to work on */
- if (totSel >= 3) {
- tSmooth_Bezt *tarray, *tsb;
-
- /* allocate memory in one go */
- tsb = tarray = MEM_callocN(totSel * sizeof(tSmooth_Bezt), "tSmooth_Bezt Array");
-
- /* populate tarray with data of selected points */
- bezt = fcu->bezt;
- for (i = 0, x = 0; (i < fcu->totvert) && (x < totSel); i++, bezt++) {
- if (BEZT_ISSEL_ANY(bezt)) {
- /* tsb simply needs pointer to vec, and index */
- tsb->h1 = &bezt->vec[0][1];
- tsb->h2 = &bezt->vec[1][1];
- tsb->h3 = &bezt->vec[2][1];
-
- /* advance to the next tsb to populate */
- if (x < totSel - 1)
- tsb++;
- else
- break;
- }
- }
-
- /* calculate the new smoothed F-Curve's with weighted averages:
- * - this is done with two passes to avoid progressive corruption errors
- * - uses 5 points for each operation (which stores in the relevant handles)
- * - previous: w/a ratio = 3:5:2:1:1
- * - next: w/a ratio = 1:1:2:5:3
- */
-
- /* round 1: calculate smoothing deltas and new values */
- tsb = tarray;
- for (i = 0; i < totSel; i++, tsb++) {
- /* don't touch end points (otherwise, curves slowly explode, as we don't have enough data there) */
- if (ELEM(i, 0, (totSel - 1)) == 0) {
- const tSmooth_Bezt *tP1 = tsb - 1;
- const tSmooth_Bezt *tP2 = (i - 2 > 0) ? (tsb - 2) : (NULL);
- const tSmooth_Bezt *tN1 = tsb + 1;
- const tSmooth_Bezt *tN2 = (i + 2 < totSel) ? (tsb + 2) : (NULL);
-
- const float p1 = *tP1->h2;
- const float p2 = (tP2) ? (*tP2->h2) : (*tP1->h2);
- const float c1 = *tsb->h2;
- const float n1 = *tN1->h2;
- const float n2 = (tN2) ? (*tN2->h2) : (*tN1->h2);
-
- /* calculate previous and next, then new position by averaging these */
- tsb->y1 = (3 * p2 + 5 * p1 + 2 * c1 + n1 + n2) / 12;
- tsb->y3 = (p2 + p1 + 2 * c1 + 5 * n1 + 3 * n2) / 12;
-
- tsb->y2 = (tsb->y1 + tsb->y3) / 2;
- }
- }
-
- /* round 2: apply new values */
- tsb = tarray;
- for (i = 0; i < totSel; i++, tsb++) {
- /* don't touch end points, as their values weren't touched above */
- if (ELEM(i, 0, (totSel - 1)) == 0) {
- /* y2 takes the average of the 2 points */
- *tsb->h2 = tsb->y2;
-
- /* handles are weighted between their original values and the averaged values */
- *tsb->h1 = ((*tsb->h1) * 0.7f) + (tsb->y1 * 0.3f);
- *tsb->h3 = ((*tsb->h3) * 0.7f) + (tsb->y3 * 0.3f);
- }
- }
-
- /* free memory required for tarray */
- MEM_freeN(tarray);
- }
-
- /* recalculate handles */
- calchandles_fcurve(fcu);
+ BezTriple *bezt;
+ int i, x, totSel = 0;
+
+ if (fcu->bezt == NULL) {
+ return;
+ }
+
+ /* first loop through - count how many verts are selected */
+ bezt = fcu->bezt;
+ for (i = 0; i < fcu->totvert; i++, bezt++) {
+ if (BEZT_ISSEL_ANY(bezt))
+ totSel++;
+ }
+
+ /* if any points were selected, allocate tSmooth_Bezt points to work on */
+ if (totSel >= 3) {
+ tSmooth_Bezt *tarray, *tsb;
+
+ /* allocate memory in one go */
+ tsb = tarray = MEM_callocN(totSel * sizeof(tSmooth_Bezt), "tSmooth_Bezt Array");
+
+ /* populate tarray with data of selected points */
+ bezt = fcu->bezt;
+ for (i = 0, x = 0; (i < fcu->totvert) && (x < totSel); i++, bezt++) {
+ if (BEZT_ISSEL_ANY(bezt)) {
+ /* tsb simply needs pointer to vec, and index */
+ tsb->h1 = &bezt->vec[0][1];
+ tsb->h2 = &bezt->vec[1][1];
+ tsb->h3 = &bezt->vec[2][1];
+
+ /* advance to the next tsb to populate */
+ if (x < totSel - 1)
+ tsb++;
+ else
+ break;
+ }
+ }
+
+ /* calculate the new smoothed F-Curve's with weighted averages:
+ * - this is done with two passes to avoid progressive corruption errors
+ * - uses 5 points for each operation (which stores in the relevant handles)
+ * - previous: w/a ratio = 3:5:2:1:1
+ * - next: w/a ratio = 1:1:2:5:3
+ */
+
+ /* round 1: calculate smoothing deltas and new values */
+ tsb = tarray;
+ for (i = 0; i < totSel; i++, tsb++) {
+ /* don't touch end points (otherwise, curves slowly explode, as we don't have enough data there) */
+ if (ELEM(i, 0, (totSel - 1)) == 0) {
+ const tSmooth_Bezt *tP1 = tsb - 1;
+ const tSmooth_Bezt *tP2 = (i - 2 > 0) ? (tsb - 2) : (NULL);
+ const tSmooth_Bezt *tN1 = tsb + 1;
+ const tSmooth_Bezt *tN2 = (i + 2 < totSel) ? (tsb + 2) : (NULL);
+
+ const float p1 = *tP1->h2;
+ const float p2 = (tP2) ? (*tP2->h2) : (*tP1->h2);
+ const float c1 = *tsb->h2;
+ const float n1 = *tN1->h2;
+ const float n2 = (tN2) ? (*tN2->h2) : (*tN1->h2);
+
+ /* calculate previous and next, then new position by averaging these */
+ tsb->y1 = (3 * p2 + 5 * p1 + 2 * c1 + n1 + n2) / 12;
+ tsb->y3 = (p2 + p1 + 2 * c1 + 5 * n1 + 3 * n2) / 12;
+
+ tsb->y2 = (tsb->y1 + tsb->y3) / 2;
+ }
+ }
+
+ /* round 2: apply new values */
+ tsb = tarray;
+ for (i = 0; i < totSel; i++, tsb++) {
+ /* don't touch end points, as their values weren't touched above */
+ if (ELEM(i, 0, (totSel - 1)) == 0) {
+ /* y2 takes the average of the 2 points */
+ *tsb->h2 = tsb->y2;
+
+ /* handles are weighted between their original values and the averaged values */
+ *tsb->h1 = ((*tsb->h1) * 0.7f) + (tsb->y1 * 0.3f);
+ *tsb->h3 = ((*tsb->h3) * 0.7f) + (tsb->y3 * 0.3f);
+ }
+ }
+
+ /* free memory required for tarray */
+ MEM_freeN(tarray);
+ }
+
+ /* recalculate handles */
+ calchandles_fcurve(fcu);
}
/* ---------------- */
/* little cache for values... */
typedef struct TempFrameValCache {
- float frame, val;
+ float frame, val;
} TempFrameValCache;
-
/* Evaluates the curves between each selected keyframe on each frame, and keys the value */
void sample_fcurve(FCurve *fcu)
{
- BezTriple *bezt, *start = NULL, *end = NULL;
- TempFrameValCache *value_cache, *fp;
- int sfra, range;
- int i, n;
-
- if (fcu->bezt == NULL) /* ignore baked */
- return;
-
- /* find selected keyframes... once pair has been found, add keyframes */
- for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
- /* check if selected, and which end this is */
- if (BEZT_ISSEL_ANY(bezt)) {
- if (start) {
- /* If next bezt is also selected, don't start sampling yet,
- * but instead wait for that one to reconsider, to avoid
- * changing the curve when sampling consecutive segments
- * (T53229)
- */
- if (i < fcu->totvert - 1) {
- BezTriple *next = &fcu->bezt[i + 1];
- if (BEZT_ISSEL_ANY(next)) {
- continue;
- }
- }
-
- /* set end */
- end = bezt;
-
- /* cache values then add keyframes using these values, as adding
- * keyframes while sampling will affect the outcome...
- * - only start sampling+adding from index=1, so that we don't overwrite original keyframe
- */
- range = (int)(ceil(end->vec[1][0] - start->vec[1][0]));
- sfra = (int)(floor(start->vec[1][0]));
-
- if (range) {
- value_cache = MEM_callocN(sizeof(TempFrameValCache) * range, "IcuFrameValCache");
-
- /* sample values */
- for (n = 1, fp = value_cache; n < range && fp; n++, fp++) {
- fp->frame = (float)(sfra + n);
- fp->val = evaluate_fcurve(fcu, fp->frame);
- }
-
- /* add keyframes with these, tagging as 'breakdowns' */
- for (n = 1, fp = value_cache; n < range && fp; n++, fp++) {
- insert_vert_fcurve(fcu, fp->frame, fp->val, BEZT_KEYTYPE_BREAKDOWN, 1);
- }
-
- /* free temp cache */
- MEM_freeN(value_cache);
-
- /* as we added keyframes, we need to compensate so that bezt is at the right place */
- bezt = fcu->bezt + i + range - 1;
- i += (range - 1);
- }
-
- /* the current selection island has ended, so start again from scratch */
- start = NULL;
- end = NULL;
- }
- else {
- /* just set start keyframe */
- start = bezt;
- end = NULL;
- }
- }
- }
-
- /* recalculate channel's handles? */
- calchandles_fcurve(fcu);
+ BezTriple *bezt, *start = NULL, *end = NULL;
+ TempFrameValCache *value_cache, *fp;
+ int sfra, range;
+ int i, n;
+
+ if (fcu->bezt == NULL) /* ignore baked */
+ return;
+
+ /* find selected keyframes... once pair has been found, add keyframes */
+ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ /* check if selected, and which end this is */
+ if (BEZT_ISSEL_ANY(bezt)) {
+ if (start) {
+ /* If next bezt is also selected, don't start sampling yet,
+ * but instead wait for that one to reconsider, to avoid
+ * changing the curve when sampling consecutive segments
+ * (T53229)
+ */
+ if (i < fcu->totvert - 1) {
+ BezTriple *next = &fcu->bezt[i + 1];
+ if (BEZT_ISSEL_ANY(next)) {
+ continue;
+ }
+ }
+
+ /* set end */
+ end = bezt;
+
+ /* cache values then add keyframes using these values, as adding
+ * keyframes while sampling will affect the outcome...
+ * - only start sampling+adding from index=1, so that we don't overwrite original keyframe
+ */
+ range = (int)(ceil(end->vec[1][0] - start->vec[1][0]));
+ sfra = (int)(floor(start->vec[1][0]));
+
+ if (range) {
+ value_cache = MEM_callocN(sizeof(TempFrameValCache) * range, "IcuFrameValCache");
+
+ /* sample values */
+ for (n = 1, fp = value_cache; n < range && fp; n++, fp++) {
+ fp->frame = (float)(sfra + n);
+ fp->val = evaluate_fcurve(fcu, fp->frame);
+ }
+
+ /* add keyframes with these, tagging as 'breakdowns' */
+ for (n = 1, fp = value_cache; n < range && fp; n++, fp++) {
+ insert_vert_fcurve(fcu, fp->frame, fp->val, BEZT_KEYTYPE_BREAKDOWN, 1);
+ }
+
+ /* free temp cache */
+ MEM_freeN(value_cache);
+
+ /* as we added keyframes, we need to compensate so that bezt is at the right place */
+ bezt = fcu->bezt + i + range - 1;
+ i += (range - 1);
+ }
+
+ /* the current selection island has ended, so start again from scratch */
+ start = NULL;
+ end = NULL;
+ }
+ else {
+ /* just set start keyframe */
+ start = bezt;
+ end = NULL;
+ }
+ }
+ }
+
+ /* recalculate channel's handles? */
+ calchandles_fcurve(fcu);
}
/* **************************************************** */
@@ -520,46 +516,45 @@ static float animcopy_cfra = 0.0;
/* datatype for use in copy/paste buffer */
typedef struct tAnimCopybufItem {
- struct tAnimCopybufItem *next, *prev;
+ struct tAnimCopybufItem *next, *prev;
- ID *id; /* ID which owns the curve */
- bActionGroup *grp; /* Action Group */
- char *rna_path; /* RNA-Path */
- int array_index; /* array index */
+ ID *id; /* ID which owns the curve */
+ bActionGroup *grp; /* Action Group */
+ char *rna_path; /* RNA-Path */
+ int array_index; /* array index */
- int totvert; /* number of keyframes stored for this channel */
- BezTriple *bezt; /* keyframes in buffer */
+ int totvert; /* number of keyframes stored for this channel */
+ BezTriple *bezt; /* keyframes in buffer */
- short id_type; /* Result of GS(id->name)*/
- bool is_bone; /* special flag for armature bones */
+ short id_type; /* Result of GS(id->name)*/
+ bool is_bone; /* special flag for armature bones */
} tAnimCopybufItem;
-
/* This function frees any MEM_calloc'ed copy/paste buffer data */
void ANIM_fcurves_copybuf_free(void)
{
- tAnimCopybufItem *aci, *acn;
+ tAnimCopybufItem *aci, *acn;
- /* free each buffer element */
- for (aci = animcopybuf.first; aci; aci = acn) {
- acn = aci->next;
+ /* free each buffer element */
+ for (aci = animcopybuf.first; aci; aci = acn) {
+ acn = aci->next;
- /* free keyframes */
- if (aci->bezt)
- MEM_freeN(aci->bezt);
+ /* free keyframes */
+ if (aci->bezt)
+ MEM_freeN(aci->bezt);
- /* free RNA-path */
- if (aci->rna_path)
- MEM_freeN(aci->rna_path);
+ /* free RNA-path */
+ if (aci->rna_path)
+ MEM_freeN(aci->rna_path);
- /* free ourself */
- BLI_freelinkN(&animcopybuf, aci);
- }
+ /* free ourself */
+ BLI_freelinkN(&animcopybuf, aci);
+ }
- /* restore initial state */
- BLI_listbase_clear(&animcopybuf);
- animcopy_firstframe = 999999999.0f;
- animcopy_lastframe = -999999999.0f;
+ /* restore initial state */
+ BLI_listbase_clear(&animcopybuf);
+ animcopy_firstframe = 999999999.0f;
+ animcopy_lastframe = -999999999.0f;
}
/* ------------------- */
@@ -567,468 +562,501 @@ void ANIM_fcurves_copybuf_free(void)
/* This function adds data to the keyframes copy/paste buffer, freeing existing data first */
short copy_animedit_keys(bAnimContext *ac, ListBase *anim_data)
{
- bAnimListElem *ale;
- Scene *scene = ac->scene;
-
- /* clear buffer first */
- ANIM_fcurves_copybuf_free();
-
- /* assume that each of these is an F-Curve */
- for (ale = anim_data->first; ale; ale = ale->next) {
- FCurve *fcu = (FCurve *)ale->key_data;
- tAnimCopybufItem *aci;
- BezTriple *bezt, *nbezt, *newbuf;
- int i;
-
- /* firstly, check if F-Curve has any selected keyframes
- * - skip if no selected keyframes found (so no need to create unnecessary copy-buffer data)
- * - this check should also eliminate any problems associated with using sample-data
- */
- if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, ANIM_editkeyframes_ok(BEZT_OK_SELECTED), NULL) == 0)
- continue;
-
- /* init copybuf item info */
- aci = MEM_callocN(sizeof(tAnimCopybufItem), "AnimCopybufItem");
- aci->id = ale->id;
- aci->id_type = GS(ale->id->name);
- aci->grp = fcu->grp;
- aci->rna_path = MEM_dupallocN(fcu->rna_path);
- aci->array_index = fcu->array_index;
-
- /* detect if this is a bone. We do that here rather than during pasting because ID pointers will get invalidated if we undo.
- * storing the relevant information here helps avoiding crashes if we undo-repaste */
- if ((aci->id_type == ID_OB) && (((Object *)aci->id)->type == OB_ARMATURE) && aci->rna_path) {
- Object *ob = (Object *)aci->id;
- bPoseChannel *pchan;
- char *bone_name;
-
- bone_name = BLI_str_quoted_substrN(aci->rna_path, "pose.bones[");
- pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
- if (pchan) {
- aci->is_bone = true;
- }
- if (bone_name) MEM_freeN(bone_name);
- }
-
- BLI_addtail(&animcopybuf, aci);
-
- /* add selected keyframes to buffer */
- /* TODO: currently, we resize array every time we add a new vert -
- * this works ok as long as it is assumed only a few keys are copied */
- for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
- if (BEZT_ISSEL_ANY(bezt)) {
- /* add to buffer */
- newbuf = MEM_callocN(sizeof(BezTriple) * (aci->totvert + 1), "copybuf beztriple");
-
- /* assume that since we are just re-sizing the array, just copy all existing data across */
- if (aci->bezt)
- memcpy(newbuf, aci->bezt, sizeof(BezTriple) * (aci->totvert));
-
- /* copy current beztriple across too */
- nbezt = &newbuf[aci->totvert];
- *nbezt = *bezt;
-
- /* ensure copy buffer is selected so pasted keys are selected */
- BEZT_SEL_ALL(nbezt);
-
- /* free old array and set the new */
- if (aci->bezt) MEM_freeN(aci->bezt);
- aci->bezt = newbuf;
- aci->totvert++;
-
- /* check if this is the earliest frame encountered so far */
- if (bezt->vec[1][0] < animcopy_firstframe)
- animcopy_firstframe = bezt->vec[1][0];
- if (bezt->vec[1][0] > animcopy_lastframe)
- animcopy_lastframe = bezt->vec[1][0];
- }
- }
-
- }
-
- /* check if anything ended up in the buffer */
- if (ELEM(NULL, animcopybuf.first, animcopybuf.last))
- return -1;
-
- /* in case 'relative' paste method is used */
- animcopy_cfra = CFRA;
-
- /* everything went fine */
- return 0;
+ bAnimListElem *ale;
+ Scene *scene = ac->scene;
+
+ /* clear buffer first */
+ ANIM_fcurves_copybuf_free();
+
+ /* assume that each of these is an F-Curve */
+ for (ale = anim_data->first; ale; ale = ale->next) {
+ FCurve *fcu = (FCurve *)ale->key_data;
+ tAnimCopybufItem *aci;
+ BezTriple *bezt, *nbezt, *newbuf;
+ int i;
+
+ /* firstly, check if F-Curve has any selected keyframes
+ * - skip if no selected keyframes found (so no need to create unnecessary copy-buffer data)
+ * - this check should also eliminate any problems associated with using sample-data
+ */
+ if (ANIM_fcurve_keyframes_loop(
+ NULL, fcu, NULL, ANIM_editkeyframes_ok(BEZT_OK_SELECTED), NULL) == 0)
+ continue;
+
+ /* init copybuf item info */
+ aci = MEM_callocN(sizeof(tAnimCopybufItem), "AnimCopybufItem");
+ aci->id = ale->id;
+ aci->id_type = GS(ale->id->name);
+ aci->grp = fcu->grp;
+ aci->rna_path = MEM_dupallocN(fcu->rna_path);
+ aci->array_index = fcu->array_index;
+
+ /* detect if this is a bone. We do that here rather than during pasting because ID pointers will get invalidated if we undo.
+ * storing the relevant information here helps avoiding crashes if we undo-repaste */
+ if ((aci->id_type == ID_OB) && (((Object *)aci->id)->type == OB_ARMATURE) && aci->rna_path) {
+ Object *ob = (Object *)aci->id;
+ bPoseChannel *pchan;
+ char *bone_name;
+
+ bone_name = BLI_str_quoted_substrN(aci->rna_path, "pose.bones[");
+ pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
+ if (pchan) {
+ aci->is_bone = true;
+ }
+ if (bone_name)
+ MEM_freeN(bone_name);
+ }
+
+ BLI_addtail(&animcopybuf, aci);
+
+ /* add selected keyframes to buffer */
+ /* TODO: currently, we resize array every time we add a new vert -
+ * this works ok as long as it is assumed only a few keys are copied */
+ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ if (BEZT_ISSEL_ANY(bezt)) {
+ /* add to buffer */
+ newbuf = MEM_callocN(sizeof(BezTriple) * (aci->totvert + 1), "copybuf beztriple");
+
+ /* assume that since we are just re-sizing the array, just copy all existing data across */
+ if (aci->bezt)
+ memcpy(newbuf, aci->bezt, sizeof(BezTriple) * (aci->totvert));
+
+ /* copy current beztriple across too */
+ nbezt = &newbuf[aci->totvert];
+ *nbezt = *bezt;
+
+ /* ensure copy buffer is selected so pasted keys are selected */
+ BEZT_SEL_ALL(nbezt);
+
+ /* free old array and set the new */
+ if (aci->bezt)
+ MEM_freeN(aci->bezt);
+ aci->bezt = newbuf;
+ aci->totvert++;
+
+ /* check if this is the earliest frame encountered so far */
+ if (bezt->vec[1][0] < animcopy_firstframe)
+ animcopy_firstframe = bezt->vec[1][0];
+ if (bezt->vec[1][0] > animcopy_lastframe)
+ animcopy_lastframe = bezt->vec[1][0];
+ }
+ }
+ }
+
+ /* check if anything ended up in the buffer */
+ if (ELEM(NULL, animcopybuf.first, animcopybuf.last))
+ return -1;
+
+ /* in case 'relative' paste method is used */
+ animcopy_cfra = CFRA;
+
+ /* everything went fine */
+ return 0;
}
static void flip_names(tAnimCopybufItem *aci, char **name)
{
- if (aci->is_bone) {
- char *str_start;
- if ((str_start = strstr(aci->rna_path, "pose.bones["))) {
- /* ninja coding, try to change the name */
- char bname_new[MAX_VGROUP_NAME];
- char *str_iter, *str_end;
- int length, prefix_l, postfix_l;
-
- str_start += 12;
- prefix_l = str_start - aci->rna_path;
-
- str_end = strchr(str_start, '\"');
-
- length = str_end - str_start;
- postfix_l = strlen(str_end);
-
- /* more ninja stuff, temporary substitute with NULL terminator */
- str_start[length] = 0;
- BLI_string_flip_side_name(bname_new, str_start, false, sizeof(bname_new));
- str_start[length] = '\"';
-
- str_iter = *name = MEM_mallocN(sizeof(char) * (prefix_l + postfix_l + length + 1), "flipped_path");
-
- BLI_strncpy(str_iter, aci->rna_path, prefix_l + 1);
- str_iter += prefix_l;
- BLI_strncpy(str_iter, bname_new, length + 1);
- str_iter += length;
- BLI_strncpy(str_iter, str_end, postfix_l + 1);
- str_iter[postfix_l] = '\0';
- }
- }
+ if (aci->is_bone) {
+ char *str_start;
+ if ((str_start = strstr(aci->rna_path, "pose.bones["))) {
+ /* ninja coding, try to change the name */
+ char bname_new[MAX_VGROUP_NAME];
+ char *str_iter, *str_end;
+ int length, prefix_l, postfix_l;
+
+ str_start += 12;
+ prefix_l = str_start - aci->rna_path;
+
+ str_end = strchr(str_start, '\"');
+
+ length = str_end - str_start;
+ postfix_l = strlen(str_end);
+
+ /* more ninja stuff, temporary substitute with NULL terminator */
+ str_start[length] = 0;
+ BLI_string_flip_side_name(bname_new, str_start, false, sizeof(bname_new));
+ str_start[length] = '\"';
+
+ str_iter = *name = MEM_mallocN(sizeof(char) * (prefix_l + postfix_l + length + 1),
+ "flipped_path");
+
+ BLI_strncpy(str_iter, aci->rna_path, prefix_l + 1);
+ str_iter += prefix_l;
+ BLI_strncpy(str_iter, bname_new, length + 1);
+ str_iter += length;
+ BLI_strncpy(str_iter, str_end, postfix_l + 1);
+ str_iter[postfix_l] = '\0';
+ }
+ }
}
/* ------------------- */
/* most strict method: exact matches only */
-static tAnimCopybufItem *pastebuf_match_path_full(FCurve *fcu, const short from_single, const short to_simple, bool flip)
+static tAnimCopybufItem *pastebuf_match_path_full(FCurve *fcu,
+ const short from_single,
+ const short to_simple,
+ bool flip)
{
- tAnimCopybufItem *aci;
-
- for (aci = animcopybuf.first; aci; aci = aci->next) {
- if (to_simple || (aci->rna_path && fcu->rna_path)) {
- if (!to_simple && flip && aci->is_bone && fcu->rna_path) {
- if ((from_single) || (aci->array_index == fcu->array_index)) {
- char *name = NULL;
- flip_names(aci, &name);
- if (STREQ(name, fcu->rna_path)) {
- MEM_freeN(name);
- break;
- }
- MEM_freeN(name);
- }
- }
- else if (to_simple || STREQ(aci->rna_path, fcu->rna_path)) {
- if ((from_single) || (aci->array_index == fcu->array_index)) {
- break;
- }
- }
- }
- }
-
- return aci;
+ tAnimCopybufItem *aci;
+
+ for (aci = animcopybuf.first; aci; aci = aci->next) {
+ if (to_simple || (aci->rna_path && fcu->rna_path)) {
+ if (!to_simple && flip && aci->is_bone && fcu->rna_path) {
+ if ((from_single) || (aci->array_index == fcu->array_index)) {
+ char *name = NULL;
+ flip_names(aci, &name);
+ if (STREQ(name, fcu->rna_path)) {
+ MEM_freeN(name);
+ break;
+ }
+ MEM_freeN(name);
+ }
+ }
+ else if (to_simple || STREQ(aci->rna_path, fcu->rna_path)) {
+ if ((from_single) || (aci->array_index == fcu->array_index)) {
+ break;
+ }
+ }
+ }
+ }
+
+ return aci;
}
/* medium match strictness: path match only (i.e. ignore ID) */
-static tAnimCopybufItem *pastebuf_match_path_property(
- Main *bmain, FCurve *fcu, const short from_single, const short UNUSED(to_simple))
+static tAnimCopybufItem *pastebuf_match_path_property(Main *bmain,
+ FCurve *fcu,
+ const short from_single,
+ const short UNUSED(to_simple))
{
- tAnimCopybufItem *aci;
-
- for (aci = animcopybuf.first; aci; aci = aci->next) {
- /* check that paths exist */
- if (aci->rna_path && fcu->rna_path) {
- /* find the property of the fcurve and compare against the end of the tAnimCopybufItem
- * more involved since it needs to do path lookups.
- * This is not 100% reliable since the user could be editing the curves on a path that wont
- * resolve, or a bone could be renamed after copying for eg. but in normal copy & paste
- * this should work out ok.
- */
- if (BLI_findindex(which_libbase(bmain, aci->id_type), aci->id) == -1) {
- /* pedantic but the ID could have been removed, and beats crashing! */
- printf("paste_animedit_keys: error ID has been removed!\n");
- }
- else {
- PointerRNA id_ptr, rptr;
- PropertyRNA *prop;
-
- RNA_id_pointer_create(aci->id, &id_ptr);
-
- if (RNA_path_resolve_property(&id_ptr, aci->rna_path, &rptr, &prop)) {
- const char *identifier = RNA_property_identifier(prop);
- int len_id = strlen(identifier);
- int len_path = strlen(fcu->rna_path);
- if (len_id <= len_path) {
- /* note, paths which end with "] will fail with this test - Animated ID Props */
- if (STREQ(identifier, fcu->rna_path + (len_path - len_id))) {
- if ((from_single) || (aci->array_index == fcu->array_index))
- break;
- }
- }
- }
- else {
- printf("paste_animedit_keys: failed to resolve path id:%s, '%s'!\n", aci->id->name, aci->rna_path);
- }
- }
- }
- }
-
- return aci;
+ tAnimCopybufItem *aci;
+
+ for (aci = animcopybuf.first; aci; aci = aci->next) {
+ /* check that paths exist */
+ if (aci->rna_path && fcu->rna_path) {
+ /* find the property of the fcurve and compare against the end of the tAnimCopybufItem
+ * more involved since it needs to do path lookups.
+ * This is not 100% reliable since the user could be editing the curves on a path that wont
+ * resolve, or a bone could be renamed after copying for eg. but in normal copy & paste
+ * this should work out ok.
+ */
+ if (BLI_findindex(which_libbase(bmain, aci->id_type), aci->id) == -1) {
+ /* pedantic but the ID could have been removed, and beats crashing! */
+ printf("paste_animedit_keys: error ID has been removed!\n");
+ }
+ else {
+ PointerRNA id_ptr, rptr;
+ PropertyRNA *prop;
+
+ RNA_id_pointer_create(aci->id, &id_ptr);
+
+ if (RNA_path_resolve_property(&id_ptr, aci->rna_path, &rptr, &prop)) {
+ const char *identifier = RNA_property_identifier(prop);
+ int len_id = strlen(identifier);
+ int len_path = strlen(fcu->rna_path);
+ if (len_id <= len_path) {
+ /* note, paths which end with "] will fail with this test - Animated ID Props */
+ if (STREQ(identifier, fcu->rna_path + (len_path - len_id))) {
+ if ((from_single) || (aci->array_index == fcu->array_index))
+ break;
+ }
+ }
+ }
+ else {
+ printf("paste_animedit_keys: failed to resolve path id:%s, '%s'!\n",
+ aci->id->name,
+ aci->rna_path);
+ }
+ }
+ }
+ }
+
+ return aci;
}
/* least strict matching heuristic: indices only */
-static tAnimCopybufItem *pastebuf_match_index_only(FCurve *fcu, const short from_single, const short UNUSED(to_simple))
+static tAnimCopybufItem *pastebuf_match_index_only(FCurve *fcu,
+ const short from_single,
+ const short UNUSED(to_simple))
{
- tAnimCopybufItem *aci;
+ tAnimCopybufItem *aci;
- for (aci = animcopybuf.first; aci; aci = aci->next) {
- /* check that paths exist */
- if ((from_single) || (aci->array_index == fcu->array_index)) {
- break;
- }
- }
+ for (aci = animcopybuf.first; aci; aci = aci->next) {
+ /* check that paths exist */
+ if ((from_single) || (aci->array_index == fcu->array_index)) {
+ break;
+ }
+ }
- return aci;
+ return aci;
}
/* ................ */
static void do_curve_mirror_flippping(tAnimCopybufItem *aci, BezTriple *bezt)
{
- if (aci->is_bone) {
- const size_t slength = strlen(aci->rna_path);
- bool flip = false;
- if (BLI_strn_endswith(aci->rna_path, "location", slength) && aci->array_index == 0)
- flip = true;
- else if (BLI_strn_endswith(aci->rna_path, "rotation_quaternion", slength) && ELEM(aci->array_index, 2, 3))
- flip = true;
- else if (BLI_strn_endswith(aci->rna_path, "rotation_euler", slength) && ELEM(aci->array_index, 1, 2))
- flip = true;
- else if (BLI_strn_endswith(aci->rna_path, "rotation_axis_angle", slength) && ELEM(aci->array_index, 2, 3))
- flip = true;
-
- if (flip) {
- bezt->vec[0][1] = -bezt->vec[0][1];
- bezt->vec[1][1] = -bezt->vec[1][1];
- bezt->vec[2][1] = -bezt->vec[2][1];
- }
- }
+ if (aci->is_bone) {
+ const size_t slength = strlen(aci->rna_path);
+ bool flip = false;
+ if (BLI_strn_endswith(aci->rna_path, "location", slength) && aci->array_index == 0)
+ flip = true;
+ else if (BLI_strn_endswith(aci->rna_path, "rotation_quaternion", slength) &&
+ ELEM(aci->array_index, 2, 3))
+ flip = true;
+ else if (BLI_strn_endswith(aci->rna_path, "rotation_euler", slength) &&
+ ELEM(aci->array_index, 1, 2))
+ flip = true;
+ else if (BLI_strn_endswith(aci->rna_path, "rotation_axis_angle", slength) &&
+ ELEM(aci->array_index, 2, 3))
+ flip = true;
+
+ if (flip) {
+ bezt->vec[0][1] = -bezt->vec[0][1];
+ bezt->vec[1][1] = -bezt->vec[1][1];
+ bezt->vec[2][1] = -bezt->vec[2][1];
+ }
+ }
}
/* helper for paste_animedit_keys() - performs the actual pasting */
-static void paste_animedit_keys_fcurve(FCurve *fcu, tAnimCopybufItem *aci, float offset, const eKeyMergeMode merge_mode, bool flip)
+static void paste_animedit_keys_fcurve(
+ FCurve *fcu, tAnimCopybufItem *aci, float offset, const eKeyMergeMode merge_mode, bool flip)
{
- BezTriple *bezt;
- int i;
-
- /* First de-select existing FCurve's keyframes */
- for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
- BEZT_DESEL_ALL(bezt);
- }
-
- /* mix mode with existing data */
- switch (merge_mode) {
- case KEYFRAME_PASTE_MERGE_MIX:
- /* do-nothing */
- break;
-
- case KEYFRAME_PASTE_MERGE_OVER:
- /* remove all keys */
- clear_fcurve_keys(fcu);
- break;
-
- case KEYFRAME_PASTE_MERGE_OVER_RANGE:
- case KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL:
- {
- float f_min;
- float f_max;
-
- if (merge_mode == KEYFRAME_PASTE_MERGE_OVER_RANGE) {
- f_min = aci->bezt[0].vec[1][0] + offset;
- f_max = aci->bezt[aci->totvert - 1].vec[1][0] + offset;
- }
- else { /* Entire Range */
- f_min = animcopy_firstframe + offset;
- f_max = animcopy_lastframe + offset;
- }
-
- /* remove keys in range */
- if (f_min < f_max) {
- /* select verts in range for removal */
- for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
- if ((f_min < bezt[0].vec[1][0]) && (bezt[0].vec[1][0] < f_max)) {
- bezt->f2 |= SELECT;
- }
- }
-
- /* remove frames in the range */
- delete_fcurve_keys(fcu);
- }
- break;
- }
- }
-
- /* just start pasting, with the first keyframe on the current frame, and so on */
- for (i = 0, bezt = aci->bezt; i < aci->totvert; i++, bezt++) {
- /* temporarily apply offset to src beztriple while copying */
- if (flip)
- do_curve_mirror_flippping(aci, bezt);
-
- bezt->vec[0][0] += offset;
- bezt->vec[1][0] += offset;
- bezt->vec[2][0] += offset;
-
- /* insert the keyframe
- * NOTE: we do not want to inherit handles from existing keyframes in this case!
- */
-
- insert_bezt_fcurve(fcu, bezt, INSERTKEY_OVERWRITE_FULL);
-
- /* un-apply offset from src beztriple after copying */
- bezt->vec[0][0] -= offset;
- bezt->vec[1][0] -= offset;
- bezt->vec[2][0] -= offset;
-
- if (flip)
- do_curve_mirror_flippping(aci, bezt);
- }
-
- /* recalculate F-Curve's handles? */
- calchandles_fcurve(fcu);
+ BezTriple *bezt;
+ int i;
+
+ /* First de-select existing FCurve's keyframes */
+ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ BEZT_DESEL_ALL(bezt);
+ }
+
+ /* mix mode with existing data */
+ switch (merge_mode) {
+ case KEYFRAME_PASTE_MERGE_MIX:
+ /* do-nothing */
+ break;
+
+ case KEYFRAME_PASTE_MERGE_OVER:
+ /* remove all keys */
+ clear_fcurve_keys(fcu);
+ break;
+
+ case KEYFRAME_PASTE_MERGE_OVER_RANGE:
+ case KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL: {
+ float f_min;
+ float f_max;
+
+ if (merge_mode == KEYFRAME_PASTE_MERGE_OVER_RANGE) {
+ f_min = aci->bezt[0].vec[1][0] + offset;
+ f_max = aci->bezt[aci->totvert - 1].vec[1][0] + offset;
+ }
+ else { /* Entire Range */
+ f_min = animcopy_firstframe + offset;
+ f_max = animcopy_lastframe + offset;
+ }
+
+ /* remove keys in range */
+ if (f_min < f_max) {
+ /* select verts in range for removal */
+ for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
+ if ((f_min < bezt[0].vec[1][0]) && (bezt[0].vec[1][0] < f_max)) {
+ bezt->f2 |= SELECT;
+ }
+ }
+
+ /* remove frames in the range */
+ delete_fcurve_keys(fcu);
+ }
+ break;
+ }
+ }
+
+ /* just start pasting, with the first keyframe on the current frame, and so on */
+ for (i = 0, bezt = aci->bezt; i < aci->totvert; i++, bezt++) {
+ /* temporarily apply offset to src beztriple while copying */
+ if (flip)
+ do_curve_mirror_flippping(aci, bezt);
+
+ bezt->vec[0][0] += offset;
+ bezt->vec[1][0] += offset;
+ bezt->vec[2][0] += offset;
+
+ /* insert the keyframe
+ * NOTE: we do not want to inherit handles from existing keyframes in this case!
+ */
+
+ insert_bezt_fcurve(fcu, bezt, INSERTKEY_OVERWRITE_FULL);
+
+ /* un-apply offset from src beztriple after copying */
+ bezt->vec[0][0] -= offset;
+ bezt->vec[1][0] -= offset;
+ bezt->vec[2][0] -= offset;
+
+ if (flip)
+ do_curve_mirror_flippping(aci, bezt);
+ }
+
+ /* recalculate F-Curve's handles? */
+ calchandles_fcurve(fcu);
}
/* ------------------- */
const EnumPropertyItem rna_enum_keyframe_paste_offset_items[] = {
- {KEYFRAME_PASTE_OFFSET_CFRA_START, "START", 0, "Frame Start", "Paste keys starting at current frame"},
- {KEYFRAME_PASTE_OFFSET_CFRA_END, "END", 0, "Frame End", "Paste keys ending at current frame"},
- {KEYFRAME_PASTE_OFFSET_CFRA_RELATIVE, "RELATIVE", 0, "Frame Relative", "Paste keys relative to the current frame when copying"},
- {KEYFRAME_PASTE_OFFSET_NONE, "NONE", 0, "No Offset", "Paste keys from original time"},
- {0, NULL, 0, NULL, NULL},
+ {KEYFRAME_PASTE_OFFSET_CFRA_START,
+ "START",
+ 0,
+ "Frame Start",
+ "Paste keys starting at current frame"},
+ {KEYFRAME_PASTE_OFFSET_CFRA_END, "END", 0, "Frame End", "Paste keys ending at current frame"},
+ {KEYFRAME_PASTE_OFFSET_CFRA_RELATIVE,
+ "RELATIVE",
+ 0,
+ "Frame Relative",
+ "Paste keys relative to the current frame when copying"},
+ {KEYFRAME_PASTE_OFFSET_NONE, "NONE", 0, "No Offset", "Paste keys from original time"},
+ {0, NULL, 0, NULL, NULL},
};
const EnumPropertyItem rna_enum_keyframe_paste_merge_items[] = {
- {KEYFRAME_PASTE_MERGE_MIX, "MIX", 0, "Mix", "Overlay existing with new keys"},
- {KEYFRAME_PASTE_MERGE_OVER, "OVER_ALL", 0, "Overwrite All", "Replace all keys"},
- {KEYFRAME_PASTE_MERGE_OVER_RANGE, "OVER_RANGE", 0, "Overwrite Range", "Overwrite keys in pasted range"},
- {KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL, "OVER_RANGE_ALL", 0, "Overwrite Entire Range", "Overwrite keys in pasted range, using the range of all copied keys"},
- {0, NULL, 0, NULL, NULL},
+ {KEYFRAME_PASTE_MERGE_MIX, "MIX", 0, "Mix", "Overlay existing with new keys"},
+ {KEYFRAME_PASTE_MERGE_OVER, "OVER_ALL", 0, "Overwrite All", "Replace all keys"},
+ {KEYFRAME_PASTE_MERGE_OVER_RANGE,
+ "OVER_RANGE",
+ 0,
+ "Overwrite Range",
+ "Overwrite keys in pasted range"},
+ {KEYFRAME_PASTE_MERGE_OVER_RANGE_ALL,
+ "OVER_RANGE_ALL",
+ 0,
+ "Overwrite Entire Range",
+ "Overwrite keys in pasted range, using the range of all copied keys"},
+ {0, NULL, 0, NULL, NULL},
};
-
/**
* This function pastes data from the keyframes copy/paste buffer
*
* \return Status code is whether the method FAILED to do anything
*/
-short paste_animedit_keys(bAnimContext *ac, ListBase *anim_data,
- const eKeyPasteOffset offset_mode, const eKeyMergeMode merge_mode, bool flip)
+short paste_animedit_keys(bAnimContext *ac,
+ ListBase *anim_data,
+ const eKeyPasteOffset offset_mode,
+ const eKeyMergeMode merge_mode,
+ bool flip)
{
- bAnimListElem *ale;
-
- const Scene *scene = (ac->scene);
-
- const bool from_single = BLI_listbase_is_single(&animcopybuf);
- const bool to_simple = BLI_listbase_is_single(anim_data);
-
- float offset = 0.0f;
- int pass;
-
- /* check if buffer is empty */
- if (BLI_listbase_is_empty(&animcopybuf)) {
- BKE_report(ac->reports, RPT_ERROR, "No animation data in buffer to paste");
- return -1;
- }
-
- if (BLI_listbase_is_empty(anim_data)) {
- BKE_report(ac->reports, RPT_ERROR, "No selected F-Curves to paste into");
- return -1;
- }
-
- /* methods of offset */
- switch (offset_mode) {
- case KEYFRAME_PASTE_OFFSET_CFRA_START:
- offset = (float)(CFRA - animcopy_firstframe);
- break;
- case KEYFRAME_PASTE_OFFSET_CFRA_END:
- offset = (float)(CFRA - animcopy_lastframe);
- break;
- case KEYFRAME_PASTE_OFFSET_CFRA_RELATIVE:
- offset = (float)(CFRA - animcopy_cfra);
- break;
- case KEYFRAME_PASTE_OFFSET_NONE:
- offset = 0.0f;
- break;
- }
-
- if (from_single && to_simple) {
- /* 1:1 match, no tricky checking, just paste */
- FCurve *fcu;
- tAnimCopybufItem *aci;
-
- ale = anim_data->first;
- fcu = (FCurve *)ale->data; /* destination F-Curve */
- aci = animcopybuf.first;
-
- paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, false);
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
- else {
- /* from selected channels
- * This "passes" system aims to try to find "matching" channels to paste keyframes
- * into with increasingly loose matching heuristics. The process finishes when at least
- * one F-Curve has been pasted into.
- */
- for (pass = 0; pass < 3; pass++) {
- unsigned int totmatch = 0;
-
- for (ale = anim_data->first; ale; ale = ale->next) {
- /* find buffer item to paste from
- * - if names don't matter (i.e. only 1 channel in buffer), don't check id/group
- * - if names do matter, only check if id-type is ok for now (group check is not that important)
- * - most importantly, rna-paths should match (array indices are unimportant for now)
- */
- AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- FCurve *fcu = (FCurve *)ale->data; /* destination F-Curve */
- tAnimCopybufItem *aci = NULL;
-
- switch (pass) {
- case 0:
- /* most strict, must be exact path match data_path & index */
- aci = pastebuf_match_path_full(fcu, from_single, to_simple, flip);
- break;
-
- case 1:
- /* less strict, just compare property names */
- aci = pastebuf_match_path_property(ac->bmain, fcu, from_single, to_simple);
- break;
-
- case 2:
- /* Comparing properties gave no results, so just do index comparisons */
- aci = pastebuf_match_index_only(fcu, from_single, to_simple);
- break;
- }
-
- /* copy the relevant data from the matching buffer curve */
- if (aci) {
- totmatch++;
-
- if (adt) {
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
- paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, flip);
- ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
- }
- else {
- paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, flip);
- }
- }
-
- ale->update |= ANIM_UPDATE_DEFAULT;
- }
-
- /* don't continue if some fcurves were pasted */
- if (totmatch)
- break;
- }
- }
-
- ANIM_animdata_update(ac, anim_data);
-
- return 0;
+ bAnimListElem *ale;
+
+ const Scene *scene = (ac->scene);
+
+ const bool from_single = BLI_listbase_is_single(&animcopybuf);
+ const bool to_simple = BLI_listbase_is_single(anim_data);
+
+ float offset = 0.0f;
+ int pass;
+
+ /* check if buffer is empty */
+ if (BLI_listbase_is_empty(&animcopybuf)) {
+ BKE_report(ac->reports, RPT_ERROR, "No animation data in buffer to paste");
+ return -1;
+ }
+
+ if (BLI_listbase_is_empty(anim_data)) {
+ BKE_report(ac->reports, RPT_ERROR, "No selected F-Curves to paste into");
+ return -1;
+ }
+
+ /* methods of offset */
+ switch (offset_mode) {
+ case KEYFRAME_PASTE_OFFSET_CFRA_START:
+ offset = (float)(CFRA - animcopy_firstframe);
+ break;
+ case KEYFRAME_PASTE_OFFSET_CFRA_END:
+ offset = (float)(CFRA - animcopy_lastframe);
+ break;
+ case KEYFRAME_PASTE_OFFSET_CFRA_RELATIVE:
+ offset = (float)(CFRA - animcopy_cfra);
+ break;
+ case KEYFRAME_PASTE_OFFSET_NONE:
+ offset = 0.0f;
+ break;
+ }
+
+ if (from_single && to_simple) {
+ /* 1:1 match, no tricky checking, just paste */
+ FCurve *fcu;
+ tAnimCopybufItem *aci;
+
+ ale = anim_data->first;
+ fcu = (FCurve *)ale->data; /* destination F-Curve */
+ aci = animcopybuf.first;
+
+ paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, false);
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+ else {
+ /* from selected channels
+ * This "passes" system aims to try to find "matching" channels to paste keyframes
+ * into with increasingly loose matching heuristics. The process finishes when at least
+ * one F-Curve has been pasted into.
+ */
+ for (pass = 0; pass < 3; pass++) {
+ unsigned int totmatch = 0;
+
+ for (ale = anim_data->first; ale; ale = ale->next) {
+ /* find buffer item to paste from
+ * - if names don't matter (i.e. only 1 channel in buffer), don't check id/group
+ * - if names do matter, only check if id-type is ok for now (group check is not that important)
+ * - most importantly, rna-paths should match (array indices are unimportant for now)
+ */
+ AnimData *adt = ANIM_nla_mapping_get(ac, ale);
+ FCurve *fcu = (FCurve *)ale->data; /* destination F-Curve */
+ tAnimCopybufItem *aci = NULL;
+
+ switch (pass) {
+ case 0:
+ /* most strict, must be exact path match data_path & index */
+ aci = pastebuf_match_path_full(fcu, from_single, to_simple, flip);
+ break;
+
+ case 1:
+ /* less strict, just compare property names */
+ aci = pastebuf_match_path_property(ac->bmain, fcu, from_single, to_simple);
+ break;
+
+ case 2:
+ /* Comparing properties gave no results, so just do index comparisons */
+ aci = pastebuf_match_index_only(fcu, from_single, to_simple);
+ break;
+ }
+
+ /* copy the relevant data from the matching buffer curve */
+ if (aci) {
+ totmatch++;
+
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
+ paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, flip);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
+ }
+ else {
+ paste_animedit_keys_fcurve(fcu, aci, offset, merge_mode, flip);
+ }
+ }
+
+ ale->update |= ANIM_UPDATE_DEFAULT;
+ }
+
+ /* don't continue if some fcurves were pasted */
+ if (totmatch)
+ break;
+ }
+ }
+
+ ANIM_animdata_update(ac, anim_data);
+
+ return 0;
}
/* **************************************************** */
diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c
index 793a73e6939..cc8dbbca439 100644
--- a/source/blender/editors/animation/keyframing.c
+++ b/source/blender/editors/animation/keyframing.c
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
#include <stdio.h>
#include <stddef.h>
#include <string.h>
@@ -80,7 +79,9 @@
#include "anim_intern.h"
-static KeyingSet *keyingset_get_from_op_with_error(wmOperator *op, PropertyRNA *prop, Scene *scene);
+static KeyingSet *keyingset_get_from_op_with_error(wmOperator *op,
+ PropertyRNA *prop,
+ Scene *scene);
/* ************************************************** */
/* Keyframing Setting Wrangling */
@@ -88,35 +89,35 @@ static KeyingSet *keyingset_get_from_op_with_error(wmOperator *op, PropertyRNA *
/* Get the active settings for keyframing settings from context (specifically the given scene) */
short ANIM_get_keyframing_flags(Scene *scene, short incl_mode)
{
- eInsertKeyFlags flag = INSERTKEY_NOFLAGS;
-
- /* standard flags */
- {
- /* visual keying */
- if (IS_AUTOKEY_FLAG(scene, AUTOMATKEY))
- flag |= INSERTKEY_MATRIX;
-
- /* only needed */
- if (IS_AUTOKEY_FLAG(scene, INSERTNEEDED))
- flag |= INSERTKEY_NEEDED;
-
- /* default F-Curve color mode - RGB from XYZ indices */
- if (IS_AUTOKEY_FLAG(scene, XYZ2RGB))
- flag |= INSERTKEY_XYZ2RGB;
- }
-
- /* only if including settings from the autokeying mode... */
- if (incl_mode) {
- /* keyframing mode - only replace existing keyframes */
- if (IS_AUTOKEY_MODE(scene, EDITKEYS))
- flag |= INSERTKEY_REPLACE;
-
- /* cycle-aware keyframe insertion - preserve cycle period and flow */
- if (IS_AUTOKEY_FLAG(scene, CYCLEAWARE))
- flag |= INSERTKEY_CYCLE_AWARE;
- }
-
- return flag;
+ eInsertKeyFlags flag = INSERTKEY_NOFLAGS;
+
+ /* standard flags */
+ {
+ /* visual keying */
+ if (IS_AUTOKEY_FLAG(scene, AUTOMATKEY))
+ flag |= INSERTKEY_MATRIX;
+
+ /* only needed */
+ if (IS_AUTOKEY_FLAG(scene, INSERTNEEDED))
+ flag |= INSERTKEY_NEEDED;
+
+ /* default F-Curve color mode - RGB from XYZ indices */
+ if (IS_AUTOKEY_FLAG(scene, XYZ2RGB))
+ flag |= INSERTKEY_XYZ2RGB;
+ }
+
+ /* only if including settings from the autokeying mode... */
+ if (incl_mode) {
+ /* keyframing mode - only replace existing keyframes */
+ if (IS_AUTOKEY_MODE(scene, EDITKEYS))
+ flag |= INSERTKEY_REPLACE;
+
+ /* cycle-aware keyframe insertion - preserve cycle period and flow */
+ if (IS_AUTOKEY_FLAG(scene, CYCLEAWARE))
+ flag |= INSERTKEY_CYCLE_AWARE;
+ }
+
+ return flag;
}
/* ******************************************* */
@@ -127,140 +128,145 @@ short ANIM_get_keyframing_flags(Scene *scene, short incl_mode)
*/
bAction *verify_adt_action(Main *bmain, ID *id, short add)
{
- AnimData *adt;
-
- /* init animdata if none available yet */
- adt = BKE_animdata_from_id(id);
- if ((adt == NULL) && (add))
- adt = BKE_animdata_add_id(id);
- if (adt == NULL) {
- /* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
- printf("ERROR: Couldn't add AnimData (ID = %s)\n", (id) ? (id->name) : "<None>");
- return NULL;
- }
-
- /* init action if none available yet */
- /* TODO: need some wizardry to handle NLA stuff correct */
- if ((adt->action == NULL) && (add)) {
- /* init action name from name of ID block */
- char actname[sizeof(id->name) - 2];
- BLI_snprintf(actname, sizeof(actname), "%sAction", id->name + 2);
-
- /* create action */
- adt->action = BKE_action_add(bmain, actname);
-
- /* set ID-type from ID-block that this is going to be assigned to
- * so that users can't accidentally break actions by assigning them
- * to the wrong places
- */
- adt->action->idroot = GS(id->name);
-
- /* Tag depsgraph to be rebuilt to include time dependency. */
- DEG_relations_tag_update(bmain);
- }
-
- DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
-
- /* return the action */
- return adt->action;
+ AnimData *adt;
+
+ /* init animdata if none available yet */
+ adt = BKE_animdata_from_id(id);
+ if ((adt == NULL) && (add))
+ adt = BKE_animdata_add_id(id);
+ if (adt == NULL) {
+ /* if still none (as not allowed to add, or ID doesn't have animdata for some reason) */
+ printf("ERROR: Couldn't add AnimData (ID = %s)\n", (id) ? (id->name) : "<None>");
+ return NULL;
+ }
+
+ /* init action if none available yet */
+ /* TODO: need some wizardry to handle NLA stuff correct */
+ if ((adt->action == NULL) && (add)) {
+ /* init action name from name of ID block */
+ char actname[sizeof(id->name) - 2];
+ BLI_snprintf(actname, sizeof(actname), "%sAction", id->name + 2);
+
+ /* create action */
+ adt->action = BKE_action_add(bmain, actname);
+
+ /* set ID-type from ID-block that this is going to be assigned to
+ * so that users can't accidentally break actions by assigning them
+ * to the wrong places
+ */
+ adt->action->idroot = GS(id->name);
+
+ /* Tag depsgraph to be rebuilt to include time dependency. */
+ DEG_relations_tag_update(bmain);
+ }
+
+ DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
+
+ /* return the action */
+ return adt->action;
}
/* Get (or add relevant data to be able to do so) F-Curve from the Active Action,
* for the given Animation Data block. This assumes that all the destinations are valid.
*/
-FCurve *verify_fcurve(Main *bmain, bAction *act, const char group[], PointerRNA *ptr,
- const char rna_path[], const int array_index, short add)
+FCurve *verify_fcurve(Main *bmain,
+ bAction *act,
+ const char group[],
+ PointerRNA *ptr,
+ const char rna_path[],
+ const int array_index,
+ short add)
{
- bActionGroup *agrp;
- FCurve *fcu;
-
- /* sanity checks */
- if (ELEM(NULL, act, rna_path))
- return NULL;
-
- /* try to find f-curve matching for this setting
- * - add if not found and allowed to add one
- * TODO: add auto-grouping support? how this works will need to be resolved
- */
- fcu = list_find_fcurve(&act->curves, rna_path, array_index);
-
- if ((fcu == NULL) && (add)) {
- /* use default settings to make a F-Curve */
- fcu = MEM_callocN(sizeof(FCurve), "FCurve");
-
- fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
- fcu->auto_smoothing = FCURVE_SMOOTH_CONT_ACCEL;
- if (BLI_listbase_is_empty(&act->curves))
- fcu->flag |= FCURVE_ACTIVE; /* first one added active */
-
- /* store path - make copy, and store that */
- fcu->rna_path = BLI_strdup(rna_path);
- fcu->array_index = array_index;
-
- /* if a group name has been provided, try to add or find a group, then add F-Curve to it */
- if (group) {
- /* try to find group */
- agrp = BKE_action_group_find_name(act, group);
-
- /* no matching groups, so add one */
- if (agrp == NULL) {
- agrp = action_groups_add_new(act, group);
-
- /* sync bone group colors if applicable */
- if (ptr && (ptr->type == &RNA_PoseBone)) {
- Object *ob = (Object *)ptr->id.data;
- bPoseChannel *pchan = (bPoseChannel *)ptr->data;
- bPose *pose = ob->pose;
- bActionGroup *grp;
-
- /* find bone group (if present), and use the color from that */
- grp = (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
- if (grp) {
- agrp->customCol = grp->customCol;
- action_group_colors_sync(agrp, grp);
- }
- }
- }
-
- /* add F-Curve to group */
- action_groups_add_channel(act, agrp, fcu);
- }
- else {
- /* just add F-Curve to end of Action's list */
- BLI_addtail(&act->curves, fcu);
- }
-
- /* New f-curve was added, meaning it's possible that it affects
- * dependency graph component which wasn't previously animated.
- */
- DEG_relations_tag_update(bmain);
- }
-
- /* return the F-Curve */
- return fcu;
+ bActionGroup *agrp;
+ FCurve *fcu;
+
+ /* sanity checks */
+ if (ELEM(NULL, act, rna_path))
+ return NULL;
+
+ /* try to find f-curve matching for this setting
+ * - add if not found and allowed to add one
+ * TODO: add auto-grouping support? how this works will need to be resolved
+ */
+ fcu = list_find_fcurve(&act->curves, rna_path, array_index);
+
+ if ((fcu == NULL) && (add)) {
+ /* use default settings to make a F-Curve */
+ fcu = MEM_callocN(sizeof(FCurve), "FCurve");
+
+ fcu->flag = (FCURVE_VISIBLE | FCURVE_SELECTED);
+ fcu->auto_smoothing = FCURVE_SMOOTH_CONT_ACCEL;
+ if (BLI_listbase_is_empty(&act->curves))
+ fcu->flag |= FCURVE_ACTIVE; /* first one added active */
+
+ /* store path - make copy, and store that */
+ fcu->rna_path = BLI_strdup(rna_path);
+ fcu->array_index = array_index;
+
+ /* if a group name has been provided, try to add or find a group, then add F-Curve to it */
+ if (group) {
+ /* try to find group */
+ agrp = BKE_action_group_find_name(act, group);
+
+ /* no matching groups, so add one */
+ if (agrp == NULL) {
+ agrp = action_groups_add_new(act, group);
+
+ /* sync bone group colors if applicable */
+ if (ptr && (ptr->type == &RNA_PoseBone)) {
+ Object *ob = (Object *)ptr->id.data;
+ bPoseChannel *pchan = (bPoseChannel *)ptr->data;
+ bPose *pose = ob->pose;
+ bActionGroup *grp;
+
+ /* find bone group (if present), and use the color from that */
+ grp = (bActionGroup *)BLI_findlink(&pose->agroups, (pchan->agrp_index - 1));
+ if (grp) {
+ agrp->customCol = grp->customCol;
+ action_group_colors_sync(agrp, grp);
+ }
+ }
+ }
+
+ /* add F-Curve to group */
+ action_groups_add_channel(act, agrp, fcu);
+ }
+ else {
+ /* just add F-Curve to end of Action's list */
+ BLI_addtail(&act->curves, fcu);
+ }
+
+ /* New f-curve was added, meaning it's possible that it affects
+ * dependency graph component which wasn't previously animated.
+ */
+ DEG_relations_tag_update(bmain);
+ }
+
+ /* return the F-Curve */
+ return fcu;
}
/* Helper for update_autoflags_fcurve() */
static void update_autoflags_fcurve_direct(FCurve *fcu, PropertyRNA *prop)
{
- /* set additional flags for the F-Curve (i.e. only integer values) */
- fcu->flag &= ~(FCURVE_INT_VALUES | FCURVE_DISCRETE_VALUES);
- switch (RNA_property_type(prop)) {
- case PROP_FLOAT:
- /* do nothing */
- break;
- case PROP_INT:
- /* do integer (only 'whole' numbers) interpolation between all points */
- fcu->flag |= FCURVE_INT_VALUES;
- break;
- default:
- /* do 'discrete' (i.e. enum, boolean values which cannot take any intermediate
- * values at all) interpolation between all points
- * - however, we must also ensure that evaluated values are only integers still
- */
- fcu->flag |= (FCURVE_DISCRETE_VALUES | FCURVE_INT_VALUES);
- break;
- }
+ /* set additional flags for the F-Curve (i.e. only integer values) */
+ fcu->flag &= ~(FCURVE_INT_VALUES | FCURVE_DISCRETE_VALUES);
+ switch (RNA_property_type(prop)) {
+ case PROP_FLOAT:
+ /* do nothing */
+ break;
+ case PROP_INT:
+ /* do integer (only 'whole' numbers) interpolation between all points */
+ fcu->flag |= FCURVE_INT_VALUES;
+ break;
+ default:
+ /* do 'discrete' (i.e. enum, boolean values which cannot take any intermediate
+ * values at all) interpolation between all points
+ * - however, we must also ensure that evaluated values are only integers still
+ */
+ fcu->flag |= (FCURVE_DISCRETE_VALUES | FCURVE_INT_VALUES);
+ break;
+ }
}
/* Update integer/discrete flags of the FCurve (used when creating/inserting keyframes,
@@ -268,34 +274,36 @@ static void update_autoflags_fcurve_direct(FCurve *fcu, PropertyRNA *prop)
*/
void update_autoflags_fcurve(FCurve *fcu, bContext *C, ReportList *reports, PointerRNA *ptr)
{
- PointerRNA tmp_ptr;
- PropertyRNA *prop;
- int old_flag = fcu->flag;
-
- if ((ptr->id.data == NULL) && (ptr->data == NULL)) {
- BKE_report(reports, RPT_ERROR, "No RNA pointer available to retrieve values for this fcurve");
- return;
- }
-
- /* try to get property we should be affecting */
- if (RNA_path_resolve_property(ptr, fcu->rna_path, &tmp_ptr, &prop) == false) {
- /* property not found... */
- const char *idname = (ptr->id.data) ? ((ID *)ptr->id.data)->name : TIP_("<No ID pointer>");
-
- BKE_reportf(reports, RPT_ERROR,
- "Could not update flags for this fcurve, as RNA path is invalid for the given ID "
- "(ID = %s, path = %s)",
- idname, fcu->rna_path);
- return;
- }
-
- /* update F-Curve flags */
- update_autoflags_fcurve_direct(fcu, prop);
-
- if (old_flag != fcu->flag) {
- /* Same as if keyframes had been changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- }
+ PointerRNA tmp_ptr;
+ PropertyRNA *prop;
+ int old_flag = fcu->flag;
+
+ if ((ptr->id.data == NULL) && (ptr->data == NULL)) {
+ BKE_report(reports, RPT_ERROR, "No RNA pointer available to retrieve values for this fcurve");
+ return;
+ }
+
+ /* try to get property we should be affecting */
+ if (RNA_path_resolve_property(ptr, fcu->rna_path, &tmp_ptr, &prop) == false) {
+ /* property not found... */
+ const char *idname = (ptr->id.data) ? ((ID *)ptr->id.data)->name : TIP_("<No ID pointer>");
+
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "Could not update flags for this fcurve, as RNA path is invalid for the given ID "
+ "(ID = %s, path = %s)",
+ idname,
+ fcu->rna_path);
+ return;
+ }
+
+ /* update F-Curve flags */
+ update_autoflags_fcurve_direct(fcu, prop);
+
+ if (old_flag != fcu->flag) {
+ /* Same as if keyframes had been changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ }
}
/* ************************************************** */
@@ -306,40 +314,40 @@ void update_autoflags_fcurve(FCurve *fcu, bContext *C, ReportList *reports, Poin
*/
static eFCU_Cycle_Type remap_cyclic_keyframe_location(FCurve *fcu, float *px, float *py)
{
- if (fcu->totvert < 2 || !fcu->bezt) {
- return FCU_CYCLE_NONE;
- }
+ if (fcu->totvert < 2 || !fcu->bezt) {
+ return FCU_CYCLE_NONE;
+ }
- eFCU_Cycle_Type type = BKE_fcurve_get_cycle_type(fcu);
+ eFCU_Cycle_Type type = BKE_fcurve_get_cycle_type(fcu);
- if (type == FCU_CYCLE_NONE) {
- return FCU_CYCLE_NONE;
- }
+ if (type == FCU_CYCLE_NONE) {
+ return FCU_CYCLE_NONE;
+ }
- BezTriple *first = &fcu->bezt[0], *last = &fcu->bezt[fcu->totvert - 1];
- float start = first->vec[1][0], end = last->vec[1][0];
+ BezTriple *first = &fcu->bezt[0], *last = &fcu->bezt[fcu->totvert - 1];
+ float start = first->vec[1][0], end = last->vec[1][0];
- if (start >= end) {
- return FCU_CYCLE_NONE;
- }
+ if (start >= end) {
+ return FCU_CYCLE_NONE;
+ }
- if (*px < start || *px > end) {
- float period = end - start;
- float step = floorf((*px - start) / period);
- *px -= step * period;
+ if (*px < start || *px > end) {
+ float period = end - start;
+ float step = floorf((*px - start) / period);
+ *px -= step * period;
- if (type == FCU_CYCLE_OFFSET) {
- /* Nasty check to handle the case when the modes are different better. */
- FMod_Cycles *data = ((FModifier *)fcu->modifiers.first)->data;
- short mode = (step >= 0) ? data->after_mode : data->before_mode;
+ if (type == FCU_CYCLE_OFFSET) {
+ /* Nasty check to handle the case when the modes are different better. */
+ FMod_Cycles *data = ((FModifier *)fcu->modifiers.first)->data;
+ short mode = (step >= 0) ? data->after_mode : data->before_mode;
- if (mode == FCM_EXTRAPOLATE_CYCLIC_OFFSET) {
- *py -= step * (last->vec[1][1] - first->vec[1][1]);
- }
- }
- }
+ if (mode == FCM_EXTRAPOLATE_CYCLIC_OFFSET) {
+ *py -= step * (last->vec[1][1] - first->vec[1][1]);
+ }
+ }
+ }
- return type;
+ return type;
}
/* -------------- BezTriple Insertion -------------------- */
@@ -347,19 +355,19 @@ static eFCU_Cycle_Type remap_cyclic_keyframe_location(FCurve *fcu, float *px, fl
/* Change the Y position of a keyframe to match the input, adjusting handles. */
static void replace_bezt_keyframe_ypos(BezTriple *dst, const BezTriple *bezt)
{
- /* just change the values when replacing, so as to not overwrite handles */
- float dy = bezt->vec[1][1] - dst->vec[1][1];
+ /* just change the values when replacing, so as to not overwrite handles */
+ float dy = bezt->vec[1][1] - dst->vec[1][1];
- /* just apply delta value change to the handle values */
- dst->vec[0][1] += dy;
- dst->vec[1][1] += dy;
- dst->vec[2][1] += dy;
+ /* just apply delta value change to the handle values */
+ dst->vec[0][1] += dy;
+ dst->vec[1][1] += dy;
+ dst->vec[2][1] += dy;
- dst->f1 = bezt->f1;
- dst->f2 = bezt->f2;
- dst->f3 = bezt->f3;
+ dst->f1 = bezt->f1;
+ dst->f2 = bezt->f2;
+ dst->f3 = bezt->f3;
- /* TODO: perform some other operations? */
+ /* TODO: perform some other operations? */
}
/* This function adds a given BezTriple to an F-Curve. It will allocate
@@ -371,81 +379,81 @@ static void replace_bezt_keyframe_ypos(BezTriple *dst, const BezTriple *bezt)
*/
int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag)
{
- int i = 0;
-
- /* are there already keyframes? */
- if (fcu->bezt) {
- bool replace;
- i = binarysearch_bezt_index(fcu->bezt, bezt->vec[1][0], fcu->totvert, &replace);
-
- /* replace an existing keyframe? */
- if (replace) {
- /* sanity check: 'i' may in rare cases exceed arraylen */
- if ((i >= 0) && (i < fcu->totvert)) {
- if (flag & INSERTKEY_OVERWRITE_FULL) {
- fcu->bezt[i] = *bezt;
- }
- else {
- replace_bezt_keyframe_ypos(&fcu->bezt[i], bezt);
- }
-
- if (flag & INSERTKEY_CYCLE_AWARE) {
- /* If replacing an end point of a cyclic curve without offset, modify the other end too. */
- if ((i == 0 || i == fcu->totvert - 1) && BKE_fcurve_get_cycle_type(fcu) == FCU_CYCLE_PERFECT) {
- replace_bezt_keyframe_ypos(&fcu->bezt[i == 0 ? fcu->totvert - 1 : 0], bezt);
- }
- }
- }
- }
- /* keyframing modes allow to not replace keyframe */
- else if ((flag & INSERTKEY_REPLACE) == 0) {
- /* insert new - if we're not restricted to replacing keyframes only */
- BezTriple *newb = MEM_callocN((fcu->totvert + 1) * sizeof(BezTriple), "beztriple");
-
- /* add the beztriples that should occur before the beztriple to be pasted (originally in fcu) */
- if (i > 0)
- memcpy(newb, fcu->bezt, i * sizeof(BezTriple));
-
- /* add beztriple to paste at index i */
- *(newb + i) = *bezt;
-
- /* add the beztriples that occur after the beztriple to be pasted (originally in fcu) */
- if (i < fcu->totvert)
- memcpy(newb + i + 1, fcu->bezt + i, (fcu->totvert - i) * sizeof(BezTriple));
-
- /* replace (+ free) old with new, only if necessary to do so */
- MEM_freeN(fcu->bezt);
- fcu->bezt = newb;
-
- fcu->totvert++;
- }
- else {
- return -1;
- }
- }
- /* no keyframes already, but can only add if...
- * 1) keyframing modes say that keyframes can only be replaced, so adding new ones won't know
- * 2) there are no samples on the curve
- * // NOTE: maybe we may want to allow this later when doing samples -> bezt conversions,
- * // but for now, having both is asking for trouble
- */
- else if ((flag & INSERTKEY_REPLACE) == 0 && (fcu->fpt == NULL)) {
- /* create new keyframes array */
- fcu->bezt = MEM_callocN(sizeof(BezTriple), "beztriple");
- *(fcu->bezt) = *bezt;
- fcu->totvert = 1;
- }
- /* cannot add anything */
- else {
- /* return error code -1 to prevent any misunderstandings */
- return -1;
- }
-
-
- /* we need to return the index, so that some tools which do post-processing can
- * detect where we added the BezTriple in the array
- */
- return i;
+ int i = 0;
+
+ /* are there already keyframes? */
+ if (fcu->bezt) {
+ bool replace;
+ i = binarysearch_bezt_index(fcu->bezt, bezt->vec[1][0], fcu->totvert, &replace);
+
+ /* replace an existing keyframe? */
+ if (replace) {
+ /* sanity check: 'i' may in rare cases exceed arraylen */
+ if ((i >= 0) && (i < fcu->totvert)) {
+ if (flag & INSERTKEY_OVERWRITE_FULL) {
+ fcu->bezt[i] = *bezt;
+ }
+ else {
+ replace_bezt_keyframe_ypos(&fcu->bezt[i], bezt);
+ }
+
+ if (flag & INSERTKEY_CYCLE_AWARE) {
+ /* If replacing an end point of a cyclic curve without offset, modify the other end too. */
+ if ((i == 0 || i == fcu->totvert - 1) &&
+ BKE_fcurve_get_cycle_type(fcu) == FCU_CYCLE_PERFECT) {
+ replace_bezt_keyframe_ypos(&fcu->bezt[i == 0 ? fcu->totvert - 1 : 0], bezt);
+ }
+ }
+ }
+ }
+ /* keyframing modes allow to not replace keyframe */
+ else if ((flag & INSERTKEY_REPLACE) == 0) {
+ /* insert new - if we're not restricted to replacing keyframes only */
+ BezTriple *newb = MEM_callocN((fcu->totvert + 1) * sizeof(BezTriple), "beztriple");
+
+ /* add the beztriples that should occur before the beztriple to be pasted (originally in fcu) */
+ if (i > 0)
+ memcpy(newb, fcu->bezt, i * sizeof(BezTriple));
+
+ /* add beztriple to paste at index i */
+ *(newb + i) = *bezt;
+
+ /* add the beztriples that occur after the beztriple to be pasted (originally in fcu) */
+ if (i < fcu->totvert)
+ memcpy(newb + i + 1, fcu->bezt + i, (fcu->totvert - i) * sizeof(BezTriple));
+
+ /* replace (+ free) old with new, only if necessary to do so */
+ MEM_freeN(fcu->bezt);
+ fcu->bezt = newb;
+
+ fcu->totvert++;
+ }
+ else {
+ return -1;
+ }
+ }
+ /* no keyframes already, but can only add if...
+ * 1) keyframing modes say that keyframes can only be replaced, so adding new ones won't know
+ * 2) there are no samples on the curve
+ * // NOTE: maybe we may want to allow this later when doing samples -> bezt conversions,
+ * // but for now, having both is asking for trouble
+ */
+ else if ((flag & INSERTKEY_REPLACE) == 0 && (fcu->fpt == NULL)) {
+ /* create new keyframes array */
+ fcu->bezt = MEM_callocN(sizeof(BezTriple), "beztriple");
+ *(fcu->bezt) = *bezt;
+ fcu->totvert = 1;
+ }
+ /* cannot add anything */
+ else {
+ /* return error code -1 to prevent any misunderstandings */
+ return -1;
+ }
+
+ /* we need to return the index, so that some tools which do post-processing can
+ * detect where we added the BezTriple in the array
+ */
+ return i;
}
/**
@@ -457,114 +465,116 @@ int insert_bezt_fcurve(FCurve *fcu, const BezTriple *bezt, eInsertKeyFlags flag)
* \param flag: Optional flags (eInsertKeyFlags) for controlling how keys get added
* and/or whether updates get done.
*/
-int insert_vert_fcurve(FCurve *fcu, float x, float y, eBezTriple_KeyframeType keyframe_type, eInsertKeyFlags flag)
+int insert_vert_fcurve(
+ FCurve *fcu, float x, float y, eBezTriple_KeyframeType keyframe_type, eInsertKeyFlags flag)
{
- BezTriple beztr = {{{0}}};
- unsigned int oldTot = fcu->totvert;
- int a;
-
- /* set all three points, for nicer start position
- * NOTE: +/- 1 on vec.x for left and right handles is so that 'free' handles work ok...
- */
- beztr.vec[0][0] = x - 1.0f;
- beztr.vec[0][1] = y;
- beztr.vec[1][0] = x;
- beztr.vec[1][1] = y;
- beztr.vec[2][0] = x + 1.0f;
- beztr.vec[2][1] = y;
- beztr.f1 = beztr.f2 = beztr.f3 = SELECT;
-
- /* set default handle types and interpolation mode */
- if (flag & INSERTKEY_NO_USERPREF) {
- /* for Py-API, we want scripts to have predictable behavior,
- * hence the option to not depend on the userpref defaults
- */
- beztr.h1 = beztr.h2 = HD_AUTO_ANIM;
- beztr.ipo = BEZT_IPO_BEZ;
- }
- else {
- /* for UI usage - defaults should come from the userprefs and/or toolsettings */
- beztr.h1 = beztr.h2 = U.keyhandles_new; /* use default handle type here */
-
- /* use default interpolation mode, with exceptions for int/discrete values */
- beztr.ipo = U.ipo_new;
- }
-
- /* interpolation type used is constrained by the type of values the curve can take */
- if (fcu->flag & FCURVE_DISCRETE_VALUES) {
- beztr.ipo = BEZT_IPO_CONST;
- }
- else if ((beztr.ipo == BEZT_IPO_BEZ) && (fcu->flag & FCURVE_INT_VALUES)) {
- beztr.ipo = BEZT_IPO_LIN;
- }
-
- /* set keyframe type value (supplied), which should come from the scene settings in most cases */
- BEZKEYTYPE(&beztr) = keyframe_type;
-
- /* set default values for "easing" interpolation mode settings
- * NOTE: Even if these modes aren't currently used, if users switch
- * to these later, we want these to work in a sane way out of
- * the box.
- */
-
- /* "back" easing - this value used to be used when overshoot=0, but that
- * introduced discontinuities in how the param worked. */
- beztr.back = 1.70158f;
-
- /* "elastic" easing - values here were hand-optimised for a default duration of
- * ~10 frames (typical mograph motion length) */
- beztr.amplitude = 0.8f;
- beztr.period = 4.1f;
-
- /* add temp beztriple to keyframes */
- a = insert_bezt_fcurve(fcu, &beztr, flag);
-
- /* what if 'a' is a negative index?
- * for now, just exit to prevent any segfaults
- */
- if (a < 0) return -1;
-
- /* don't recalculate handles if fast is set
- * - this is a hack to make importers faster
- * - we may calculate twice (due to autohandle needing to be calculated twice)
- */
- if ((flag & INSERTKEY_FAST) == 0)
- calchandles_fcurve(fcu);
-
- /* set handletype and interpolation */
- if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE) == 0) {
- BezTriple *bezt = (fcu->bezt + a);
-
- /* set interpolation from previous (if available), but only if we didn't just replace some keyframe
- * - replacement is indicated by no-change in number of verts
- * - when replacing, the user may have specified some interpolation that should be kept
- */
- if (fcu->totvert > oldTot) {
- if (a > 0)
- bezt->ipo = (bezt - 1)->ipo;
- else if (a < fcu->totvert - 1)
- bezt->ipo = (bezt + 1)->ipo;
- }
-
- /* don't recalculate handles if fast is set
- * - this is a hack to make importers faster
- * - we may calculate twice (due to autohandle needing to be calculated twice)
- */
- if ((flag & INSERTKEY_FAST) == 0)
- calchandles_fcurve(fcu);
- }
-
- /* return the index at which the keyframe was added */
- return a;
+ BezTriple beztr = {{{0}}};
+ unsigned int oldTot = fcu->totvert;
+ int a;
+
+ /* set all three points, for nicer start position
+ * NOTE: +/- 1 on vec.x for left and right handles is so that 'free' handles work ok...
+ */
+ beztr.vec[0][0] = x - 1.0f;
+ beztr.vec[0][1] = y;
+ beztr.vec[1][0] = x;
+ beztr.vec[1][1] = y;
+ beztr.vec[2][0] = x + 1.0f;
+ beztr.vec[2][1] = y;
+ beztr.f1 = beztr.f2 = beztr.f3 = SELECT;
+
+ /* set default handle types and interpolation mode */
+ if (flag & INSERTKEY_NO_USERPREF) {
+ /* for Py-API, we want scripts to have predictable behavior,
+ * hence the option to not depend on the userpref defaults
+ */
+ beztr.h1 = beztr.h2 = HD_AUTO_ANIM;
+ beztr.ipo = BEZT_IPO_BEZ;
+ }
+ else {
+ /* for UI usage - defaults should come from the userprefs and/or toolsettings */
+ beztr.h1 = beztr.h2 = U.keyhandles_new; /* use default handle type here */
+
+ /* use default interpolation mode, with exceptions for int/discrete values */
+ beztr.ipo = U.ipo_new;
+ }
+
+ /* interpolation type used is constrained by the type of values the curve can take */
+ if (fcu->flag & FCURVE_DISCRETE_VALUES) {
+ beztr.ipo = BEZT_IPO_CONST;
+ }
+ else if ((beztr.ipo == BEZT_IPO_BEZ) && (fcu->flag & FCURVE_INT_VALUES)) {
+ beztr.ipo = BEZT_IPO_LIN;
+ }
+
+ /* set keyframe type value (supplied), which should come from the scene settings in most cases */
+ BEZKEYTYPE(&beztr) = keyframe_type;
+
+ /* set default values for "easing" interpolation mode settings
+ * NOTE: Even if these modes aren't currently used, if users switch
+ * to these later, we want these to work in a sane way out of
+ * the box.
+ */
+
+ /* "back" easing - this value used to be used when overshoot=0, but that
+ * introduced discontinuities in how the param worked. */
+ beztr.back = 1.70158f;
+
+ /* "elastic" easing - values here were hand-optimised for a default duration of
+ * ~10 frames (typical mograph motion length) */
+ beztr.amplitude = 0.8f;
+ beztr.period = 4.1f;
+
+ /* add temp beztriple to keyframes */
+ a = insert_bezt_fcurve(fcu, &beztr, flag);
+
+ /* what if 'a' is a negative index?
+ * for now, just exit to prevent any segfaults
+ */
+ if (a < 0)
+ return -1;
+
+ /* don't recalculate handles if fast is set
+ * - this is a hack to make importers faster
+ * - we may calculate twice (due to autohandle needing to be calculated twice)
+ */
+ if ((flag & INSERTKEY_FAST) == 0)
+ calchandles_fcurve(fcu);
+
+ /* set handletype and interpolation */
+ if ((fcu->totvert > 2) && (flag & INSERTKEY_REPLACE) == 0) {
+ BezTriple *bezt = (fcu->bezt + a);
+
+ /* set interpolation from previous (if available), but only if we didn't just replace some keyframe
+ * - replacement is indicated by no-change in number of verts
+ * - when replacing, the user may have specified some interpolation that should be kept
+ */
+ if (fcu->totvert > oldTot) {
+ if (a > 0)
+ bezt->ipo = (bezt - 1)->ipo;
+ else if (a < fcu->totvert - 1)
+ bezt->ipo = (bezt + 1)->ipo;
+ }
+
+ /* don't recalculate handles if fast is set
+ * - this is a hack to make importers faster
+ * - we may calculate twice (due to autohandle needing to be calculated twice)
+ */
+ if ((flag & INSERTKEY_FAST) == 0)
+ calchandles_fcurve(fcu);
+ }
+
+ /* return the index at which the keyframe was added */
+ return a;
}
/* -------------- 'Smarter' Keyframing Functions -------------------- */
/* return codes for new_key_needed */
enum {
- KEYNEEDED_DONTADD = 0,
- KEYNEEDED_JUSTADD,
- KEYNEEDED_DELPREV,
- KEYNEEDED_DELNEXT,
+ KEYNEEDED_DONTADD = 0,
+ KEYNEEDED_JUSTADD,
+ KEYNEEDED_DELPREV,
+ KEYNEEDED_DELNEXT,
} /*eKeyNeededStatus*/;
/* This helper function determines whether a new keyframe is needed */
@@ -575,187 +585,195 @@ enum {
*/
static short new_key_needed(FCurve *fcu, float cFrame, float nValue)
{
- BezTriple *bezt = NULL, *prev = NULL;
- int totCount, i;
- float valA = 0.0f, valB = 0.0f;
-
- /* safety checking */
- if (fcu == NULL) return KEYNEEDED_JUSTADD;
- totCount = fcu->totvert;
- if (totCount == 0) return KEYNEEDED_JUSTADD;
-
- /* loop through checking if any are the same */
- bezt = fcu->bezt;
- for (i = 0; i < totCount; i++) {
- float prevPosi = 0.0f, prevVal = 0.0f;
- float beztPosi = 0.0f, beztVal = 0.0f;
-
- /* get current time+value */
- beztPosi = bezt->vec[1][0];
- beztVal = bezt->vec[1][1];
-
- if (prev) {
- /* there is a keyframe before the one currently being examined */
-
- /* get previous time+value */
- prevPosi = prev->vec[1][0];
- prevVal = prev->vec[1][1];
-
- /* keyframe to be added at point where there are already two similar points? */
- if (IS_EQF(prevPosi, cFrame) && IS_EQF(beztPosi, cFrame) && IS_EQF(beztPosi, prevPosi)) {
- return KEYNEEDED_DONTADD;
- }
-
- /* keyframe between prev+current points ? */
- if ((prevPosi <= cFrame) && (cFrame <= beztPosi)) {
- /* is the value of keyframe to be added the same as keyframes on either side ? */
- if (IS_EQF(prevVal, nValue) && IS_EQF(beztVal, nValue) && IS_EQF(prevVal, beztVal)) {
- return KEYNEEDED_DONTADD;
- }
- else {
- float realVal;
-
- /* get real value of curve at that point */
- realVal = evaluate_fcurve(fcu, cFrame);
-
- /* compare whether it's the same as proposed */
- if (IS_EQF(realVal, nValue))
- return KEYNEEDED_DONTADD;
- else
- return KEYNEEDED_JUSTADD;
- }
- }
-
- /* new keyframe before prev beztriple? */
- if (cFrame < prevPosi) {
- /* A new keyframe will be added. However, whether the previous beztriple
- * stays around or not depends on whether the values of previous/current
- * beztriples and new keyframe are the same.
- */
- if (IS_EQF(prevVal, nValue) && IS_EQF(beztVal, nValue) && IS_EQF(prevVal, beztVal))
- return KEYNEEDED_DELNEXT;
- else
- return KEYNEEDED_JUSTADD;
- }
- }
- else {
- /* just add a keyframe if there's only one keyframe
- * and the new one occurs before the existing one does.
- */
- if ((cFrame < beztPosi) && (totCount == 1))
- return KEYNEEDED_JUSTADD;
- }
-
- /* continue. frame to do not yet passed (or other conditions not met) */
- if (i < (totCount - 1)) {
- prev = bezt;
- bezt++;
- }
- else
- break;
- }
-
- /* Frame in which to add a new-keyframe occurs after all other keys
- * -> If there are at least two existing keyframes, then if the values of the
- * last two keyframes and the new-keyframe match, the last existing keyframe
- * gets deleted as it is no longer required.
- * -> Otherwise, a keyframe is just added. 1.0 is added so that fake-2nd-to-last
- * keyframe is not equal to last keyframe.
- */
- bezt = (fcu->bezt + (fcu->totvert - 1));
- valA = bezt->vec[1][1];
-
- if (prev)
- valB = prev->vec[1][1];
- else
- valB = bezt->vec[1][1] + 1.0f;
-
- if (IS_EQF(valA, nValue) && IS_EQF(valA, valB))
- return KEYNEEDED_DELPREV;
- else
- return KEYNEEDED_JUSTADD;
+ BezTriple *bezt = NULL, *prev = NULL;
+ int totCount, i;
+ float valA = 0.0f, valB = 0.0f;
+
+ /* safety checking */
+ if (fcu == NULL)
+ return KEYNEEDED_JUSTADD;
+ totCount = fcu->totvert;
+ if (totCount == 0)
+ return KEYNEEDED_JUSTADD;
+
+ /* loop through checking if any are the same */
+ bezt = fcu->bezt;
+ for (i = 0; i < totCount; i++) {
+ float prevPosi = 0.0f, prevVal = 0.0f;
+ float beztPosi = 0.0f, beztVal = 0.0f;
+
+ /* get current time+value */
+ beztPosi = bezt->vec[1][0];
+ beztVal = bezt->vec[1][1];
+
+ if (prev) {
+ /* there is a keyframe before the one currently being examined */
+
+ /* get previous time+value */
+ prevPosi = prev->vec[1][0];
+ prevVal = prev->vec[1][1];
+
+ /* keyframe to be added at point where there are already two similar points? */
+ if (IS_EQF(prevPosi, cFrame) && IS_EQF(beztPosi, cFrame) && IS_EQF(beztPosi, prevPosi)) {
+ return KEYNEEDED_DONTADD;
+ }
+
+ /* keyframe between prev+current points ? */
+ if ((prevPosi <= cFrame) && (cFrame <= beztPosi)) {
+ /* is the value of keyframe to be added the same as keyframes on either side ? */
+ if (IS_EQF(prevVal, nValue) && IS_EQF(beztVal, nValue) && IS_EQF(prevVal, beztVal)) {
+ return KEYNEEDED_DONTADD;
+ }
+ else {
+ float realVal;
+
+ /* get real value of curve at that point */
+ realVal = evaluate_fcurve(fcu, cFrame);
+
+ /* compare whether it's the same as proposed */
+ if (IS_EQF(realVal, nValue))
+ return KEYNEEDED_DONTADD;
+ else
+ return KEYNEEDED_JUSTADD;
+ }
+ }
+
+ /* new keyframe before prev beztriple? */
+ if (cFrame < prevPosi) {
+ /* A new keyframe will be added. However, whether the previous beztriple
+ * stays around or not depends on whether the values of previous/current
+ * beztriples and new keyframe are the same.
+ */
+ if (IS_EQF(prevVal, nValue) && IS_EQF(beztVal, nValue) && IS_EQF(prevVal, beztVal))
+ return KEYNEEDED_DELNEXT;
+ else
+ return KEYNEEDED_JUSTADD;
+ }
+ }
+ else {
+ /* just add a keyframe if there's only one keyframe
+ * and the new one occurs before the existing one does.
+ */
+ if ((cFrame < beztPosi) && (totCount == 1))
+ return KEYNEEDED_JUSTADD;
+ }
+
+ /* continue. frame to do not yet passed (or other conditions not met) */
+ if (i < (totCount - 1)) {
+ prev = bezt;
+ bezt++;
+ }
+ else
+ break;
+ }
+
+ /* Frame in which to add a new-keyframe occurs after all other keys
+ * -> If there are at least two existing keyframes, then if the values of the
+ * last two keyframes and the new-keyframe match, the last existing keyframe
+ * gets deleted as it is no longer required.
+ * -> Otherwise, a keyframe is just added. 1.0 is added so that fake-2nd-to-last
+ * keyframe is not equal to last keyframe.
+ */
+ bezt = (fcu->bezt + (fcu->totvert - 1));
+ valA = bezt->vec[1][1];
+
+ if (prev)
+ valB = prev->vec[1][1];
+ else
+ valB = bezt->vec[1][1] + 1.0f;
+
+ if (IS_EQF(valA, nValue) && IS_EQF(valA, valB))
+ return KEYNEEDED_DELPREV;
+ else
+ return KEYNEEDED_JUSTADD;
}
/* ------------------ RNA Data-Access Functions ------------------ */
/* Try to read value using RNA-properties obtained already */
-static float *setting_get_rna_values(Depsgraph *depsgraph, PointerRNA *ptr, PropertyRNA *prop, const bool get_evaluated, float *buffer, int buffer_size, int *r_count)
+static float *setting_get_rna_values(Depsgraph *depsgraph,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ const bool get_evaluated,
+ float *buffer,
+ int buffer_size,
+ int *r_count)
{
- BLI_assert(buffer_size >= 1);
-
- float *values = buffer;
- PointerRNA ptr_eval;
-
- if (get_evaluated) {
- DEG_get_evaluated_rna_pointer(depsgraph, ptr, &ptr_eval);
- ptr = &ptr_eval;
- }
-
- if (RNA_property_array_check(prop)) {
- int length = *r_count = RNA_property_array_length(ptr, prop);
- bool *tmp_bool;
- int *tmp_int;
-
- if (length > buffer_size) {
- values = MEM_malloc_arrayN(sizeof(float), length, __func__);
- }
-
- switch (RNA_property_type(prop)) {
- case PROP_BOOLEAN:
- tmp_bool = MEM_malloc_arrayN(sizeof(*tmp_bool), length, __func__);
- RNA_property_boolean_get_array(ptr, prop, tmp_bool);
- for (int i = 0; i < length; i++) {
- values[i] = (float)tmp_bool[i];
- }
- MEM_freeN(tmp_bool);
- break;
- case PROP_INT:
- tmp_int = MEM_malloc_arrayN(sizeof(*tmp_int), length, __func__);
- RNA_property_int_get_array(ptr, prop, tmp_int);
- for (int i = 0; i < length; i++) {
- values[i] = (float)tmp_int[i];
- }
- MEM_freeN(tmp_int);
- break;
- case PROP_FLOAT:
- RNA_property_float_get_array(ptr, prop, values);
- break;
- default:
- memset(values, 0, sizeof(float) * length);
- }
- }
- else {
- *r_count = 1;
-
- switch (RNA_property_type(prop)) {
- case PROP_BOOLEAN:
- *values = (float)RNA_property_boolean_get(ptr, prop);
- break;
- case PROP_INT:
- *values = (float)RNA_property_int_get(ptr, prop);
- break;
- case PROP_FLOAT:
- *values = RNA_property_float_get(ptr, prop);
- break;
- case PROP_ENUM:
- *values = (float)RNA_property_enum_get(ptr, prop);
- break;
- default:
- *values = 0.0f;
- }
- }
-
- return values;
+ BLI_assert(buffer_size >= 1);
+
+ float *values = buffer;
+ PointerRNA ptr_eval;
+
+ if (get_evaluated) {
+ DEG_get_evaluated_rna_pointer(depsgraph, ptr, &ptr_eval);
+ ptr = &ptr_eval;
+ }
+
+ if (RNA_property_array_check(prop)) {
+ int length = *r_count = RNA_property_array_length(ptr, prop);
+ bool *tmp_bool;
+ int *tmp_int;
+
+ if (length > buffer_size) {
+ values = MEM_malloc_arrayN(sizeof(float), length, __func__);
+ }
+
+ switch (RNA_property_type(prop)) {
+ case PROP_BOOLEAN:
+ tmp_bool = MEM_malloc_arrayN(sizeof(*tmp_bool), length, __func__);
+ RNA_property_boolean_get_array(ptr, prop, tmp_bool);
+ for (int i = 0; i < length; i++) {
+ values[i] = (float)tmp_bool[i];
+ }
+ MEM_freeN(tmp_bool);
+ break;
+ case PROP_INT:
+ tmp_int = MEM_malloc_arrayN(sizeof(*tmp_int), length, __func__);
+ RNA_property_int_get_array(ptr, prop, tmp_int);
+ for (int i = 0; i < length; i++) {
+ values[i] = (float)tmp_int[i];
+ }
+ MEM_freeN(tmp_int);
+ break;
+ case PROP_FLOAT:
+ RNA_property_float_get_array(ptr, prop, values);
+ break;
+ default:
+ memset(values, 0, sizeof(float) * length);
+ }
+ }
+ else {
+ *r_count = 1;
+
+ switch (RNA_property_type(prop)) {
+ case PROP_BOOLEAN:
+ *values = (float)RNA_property_boolean_get(ptr, prop);
+ break;
+ case PROP_INT:
+ *values = (float)RNA_property_int_get(ptr, prop);
+ break;
+ case PROP_FLOAT:
+ *values = RNA_property_float_get(ptr, prop);
+ break;
+ case PROP_ENUM:
+ *values = (float)RNA_property_enum_get(ptr, prop);
+ break;
+ default:
+ *values = 0.0f;
+ }
+ }
+
+ return values;
}
/* ------------------ 'Visual' Keyframing Functions ------------------ */
/* internal status codes for visualkey_can_use */
enum {
- VISUALKEY_NONE = 0,
- VISUALKEY_LOC,
- VISUALKEY_ROT,
- VISUALKEY_SCA,
+ VISUALKEY_NONE = 0,
+ VISUALKEY_LOC,
+ VISUALKEY_ROT,
+ VISUALKEY_SCA,
};
/* This helper function determines if visual-keyframing should be used when
@@ -766,331 +784,365 @@ enum {
*/
static bool visualkey_can_use(PointerRNA *ptr, PropertyRNA *prop)
{
- bConstraint *con = NULL;
- short searchtype = VISUALKEY_NONE;
- bool has_rigidbody = false;
- bool has_parent = false;
- const char *identifier = NULL;
-
- /* validate data */
- if (ELEM(NULL, ptr, ptr->data, prop))
- return false;
-
- /* get first constraint and determine type of keyframe constraints to check for
- * - constraints can be on either Objects or PoseChannels, so we only check if the
- * ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
- * those structs, allowing us to identify the owner of the data
- */
- if (ptr->type == &RNA_Object) {
- /* Object */
- Object *ob = (Object *)ptr->data;
- RigidBodyOb *rbo = ob->rigidbody_object;
-
- con = ob->constraints.first;
- identifier = RNA_property_identifier(prop);
- has_parent = (ob->parent != NULL);
-
- /* active rigidbody objects only, as only those are affected by sim */
- has_rigidbody = ((rbo) && (rbo->type == RBO_TYPE_ACTIVE));
- }
- else if (ptr->type == &RNA_PoseBone) {
- /* Pose Channel */
- bPoseChannel *pchan = (bPoseChannel *)ptr->data;
-
- con = pchan->constraints.first;
- identifier = RNA_property_identifier(prop);
- has_parent = (pchan->parent != NULL);
- }
-
- /* check if any data to search using */
- if (ELEM(NULL, con, identifier) && (has_parent == false) && (has_rigidbody == false))
- return false;
-
- /* location or rotation identifiers only... */
- if (identifier == NULL) {
- printf("%s failed: NULL identifier\n", __func__);
- return false;
- }
- else if (strstr(identifier, "location")) {
- searchtype = VISUALKEY_LOC;
- }
- else if (strstr(identifier, "rotation")) {
- searchtype = VISUALKEY_ROT;
- }
- else if (strstr(identifier, "scale")) {
- searchtype = VISUALKEY_SCA;
- }
- else {
- printf("%s failed: identifier - '%s'\n", __func__, identifier);
- return false;
- }
-
-
- /* only search if a searchtype and initial constraint are available */
- if (searchtype) {
- /* parent or rigidbody are always matching */
- if (has_parent || has_rigidbody)
- return true;
-
- /* constraints */
- for (; con; con = con->next) {
- /* only consider constraint if it is not disabled, and has influence */
- if (con->flag & CONSTRAINT_DISABLE) continue;
- if (con->enforce == 0.0f) continue;
-
- /* some constraints may alter these transforms */
- switch (con->type) {
- /* multi-transform constraints */
- case CONSTRAINT_TYPE_CHILDOF:
- case CONSTRAINT_TYPE_ARMATURE:
- return true;
- case CONSTRAINT_TYPE_TRANSFORM:
- case CONSTRAINT_TYPE_TRANSLIKE:
- return true;
- case CONSTRAINT_TYPE_FOLLOWPATH:
- return true;
- case CONSTRAINT_TYPE_KINEMATIC:
- return true;
-
- /* single-transform constraints */
- case CONSTRAINT_TYPE_TRACKTO:
- if (searchtype == VISUALKEY_ROT) return true;
- break;
- case CONSTRAINT_TYPE_DAMPTRACK:
- if (searchtype == VISUALKEY_ROT) return true;
- break;
- case CONSTRAINT_TYPE_ROTLIMIT:
- if (searchtype == VISUALKEY_ROT) return true;
- break;
- case CONSTRAINT_TYPE_LOCLIMIT:
- if (searchtype == VISUALKEY_LOC) return true;
- break;
- case CONSTRAINT_TYPE_SIZELIMIT:
- if (searchtype == VISUALKEY_SCA) return true;
- break;
- case CONSTRAINT_TYPE_DISTLIMIT:
- if (searchtype == VISUALKEY_LOC) return true;
- break;
- case CONSTRAINT_TYPE_ROTLIKE:
- if (searchtype == VISUALKEY_ROT) return true;
- break;
- case CONSTRAINT_TYPE_LOCLIKE:
- if (searchtype == VISUALKEY_LOC) return true;
- break;
- case CONSTRAINT_TYPE_SIZELIKE:
- if (searchtype == VISUALKEY_SCA) return true;
- break;
- case CONSTRAINT_TYPE_LOCKTRACK:
- if (searchtype == VISUALKEY_ROT) return true;
- break;
- case CONSTRAINT_TYPE_MINMAX:
- if (searchtype == VISUALKEY_LOC) return true;
- break;
-
- default:
- break;
- }
- }
- }
-
- /* when some condition is met, this function returns, so that means we've got nothing */
- return false;
+ bConstraint *con = NULL;
+ short searchtype = VISUALKEY_NONE;
+ bool has_rigidbody = false;
+ bool has_parent = false;
+ const char *identifier = NULL;
+
+ /* validate data */
+ if (ELEM(NULL, ptr, ptr->data, prop))
+ return false;
+
+ /* get first constraint and determine type of keyframe constraints to check for
+ * - constraints can be on either Objects or PoseChannels, so we only check if the
+ * ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
+ * those structs, allowing us to identify the owner of the data
+ */
+ if (ptr->type == &RNA_Object) {
+ /* Object */
+ Object *ob = (Object *)ptr->data;
+ RigidBodyOb *rbo = ob->rigidbody_object;
+
+ con = ob->constraints.first;
+ identifier = RNA_property_identifier(prop);
+ has_parent = (ob->parent != NULL);
+
+ /* active rigidbody objects only, as only those are affected by sim */
+ has_rigidbody = ((rbo) && (rbo->type == RBO_TYPE_ACTIVE));
+ }
+ else if (ptr->type == &RNA_PoseBone) {
+ /* Pose Channel */
+ bPoseChannel *pchan = (bPoseChannel *)ptr->data;
+
+ con = pchan->constraints.first;
+ identifier = RNA_property_identifier(prop);
+ has_parent = (pchan->parent != NULL);
+ }
+
+ /* check if any data to search using */
+ if (ELEM(NULL, con, identifier) && (has_parent == false) && (has_rigidbody == false))
+ return false;
+
+ /* location or rotation identifiers only... */
+ if (identifier == NULL) {
+ printf("%s failed: NULL identifier\n", __func__);
+ return false;
+ }
+ else if (strstr(identifier, "location")) {
+ searchtype = VISUALKEY_LOC;
+ }
+ else if (strstr(identifier, "rotation")) {
+ searchtype = VISUALKEY_ROT;
+ }
+ else if (strstr(identifier, "scale")) {
+ searchtype = VISUALKEY_SCA;
+ }
+ else {
+ printf("%s failed: identifier - '%s'\n", __func__, identifier);
+ return false;
+ }
+
+ /* only search if a searchtype and initial constraint are available */
+ if (searchtype) {
+ /* parent or rigidbody are always matching */
+ if (has_parent || has_rigidbody)
+ return true;
+
+ /* constraints */
+ for (; con; con = con->next) {
+ /* only consider constraint if it is not disabled, and has influence */
+ if (con->flag & CONSTRAINT_DISABLE)
+ continue;
+ if (con->enforce == 0.0f)
+ continue;
+
+ /* some constraints may alter these transforms */
+ switch (con->type) {
+ /* multi-transform constraints */
+ case CONSTRAINT_TYPE_CHILDOF:
+ case CONSTRAINT_TYPE_ARMATURE:
+ return true;
+ case CONSTRAINT_TYPE_TRANSFORM:
+ case CONSTRAINT_TYPE_TRANSLIKE:
+ return true;
+ case CONSTRAINT_TYPE_FOLLOWPATH:
+ return true;
+ case CONSTRAINT_TYPE_KINEMATIC:
+ return true;
+
+ /* single-transform constraints */
+ case CONSTRAINT_TYPE_TRACKTO:
+ if (searchtype == VISUALKEY_ROT)
+ return true;
+ break;
+ case CONSTRAINT_TYPE_DAMPTRACK:
+ if (searchtype == VISUALKEY_ROT)
+ return true;
+ break;
+ case CONSTRAINT_TYPE_ROTLIMIT:
+ if (searchtype == VISUALKEY_ROT)
+ return true;
+ break;
+ case CONSTRAINT_TYPE_LOCLIMIT:
+ if (searchtype == VISUALKEY_LOC)
+ return true;
+ break;
+ case CONSTRAINT_TYPE_SIZELIMIT:
+ if (searchtype == VISUALKEY_SCA)
+ return true;
+ break;
+ case CONSTRAINT_TYPE_DISTLIMIT:
+ if (searchtype == VISUALKEY_LOC)
+ return true;
+ break;
+ case CONSTRAINT_TYPE_ROTLIKE:
+ if (searchtype == VISUALKEY_ROT)
+ return true;
+ break;
+ case CONSTRAINT_TYPE_LOCLIKE:
+ if (searchtype == VISUALKEY_LOC)
+ return true;
+ break;
+ case CONSTRAINT_TYPE_SIZELIKE:
+ if (searchtype == VISUALKEY_SCA)
+ return true;
+ break;
+ case CONSTRAINT_TYPE_LOCKTRACK:
+ if (searchtype == VISUALKEY_ROT)
+ return true;
+ break;
+ case CONSTRAINT_TYPE_MINMAX:
+ if (searchtype == VISUALKEY_LOC)
+ return true;
+ break;
+
+ default:
+ break;
+ }
+ }
+ }
+
+ /* when some condition is met, this function returns, so that means we've got nothing */
+ return false;
}
/* This helper function extracts the value to use for visual-keyframing
* In the event that it is not possible to perform visual keying, try to fall-back
* to using the default method. Assumes that all data it has been passed is valid.
*/
-static float *visualkey_get_values(Depsgraph *depsgraph, PointerRNA *ptr, PropertyRNA *prop, float *buffer, int buffer_size, int *r_count)
+static float *visualkey_get_values(Depsgraph *depsgraph,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ float *buffer,
+ int buffer_size,
+ int *r_count)
{
- BLI_assert(buffer_size >= 4);
-
- const char *identifier = RNA_property_identifier(prop);
- float tmat[4][4];
- int rotmode;
-
- /* handle for Objects or PoseChannels only
- * - only Location, Rotation or Scale keyframes are supported currently
- * - constraints can be on either Objects or PoseChannels, so we only check if the
- * ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
- * those structs, allowing us to identify the owner of the data
- * - assume that array_index will be sane
- */
- if (ptr->type == &RNA_Object) {
- Object *ob = (Object *)ptr->data;
- const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
-
- /* Loc code is specific... */
- if (strstr(identifier, "location")) {
- copy_v3_v3(buffer, ob_eval->obmat[3]);
- *r_count = 3;
- return buffer;
- }
-
- copy_m4_m4(tmat, ob_eval->obmat);
- rotmode = ob_eval->rotmode;
- }
- else if (ptr->type == &RNA_PoseBone) {
- Object *ob = (Object *)ptr->id.data;
- bPoseChannel *pchan = (bPoseChannel *)ptr->data;
-
- const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
- bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
-
- BKE_armature_mat_pose_to_bone(pchan_eval, pchan_eval->pose_mat, tmat);
- rotmode = pchan_eval->rotmode;
-
- /* Loc code is specific... */
- if (strstr(identifier, "location")) {
- /* only use for non-connected bones */
- if ((pchan->bone->parent == NULL) || !(pchan->bone->flag & BONE_CONNECTED)) {
- copy_v3_v3(buffer, tmat[3]);
- *r_count = 3;
- return buffer;
- }
- }
- }
- else {
- return setting_get_rna_values(depsgraph, ptr, prop, true, buffer, buffer_size, r_count);
- }
-
- /* Rot/Scale code are common! */
- if (strstr(identifier, "rotation_euler")) {
- mat4_to_eulO(buffer, rotmode, tmat);
-
- *r_count = 3;
- return buffer;
- }
- else if (strstr(identifier, "rotation_quaternion")) {
- float mat3[3][3];
-
- copy_m3_m4(mat3, tmat);
- mat3_to_quat_is_ok(buffer, mat3);
-
- *r_count = 4;
- return buffer;
- }
- else if (strstr(identifier, "rotation_axis_angle")) {
- /* w = 0, x,y,z = 1,2,3 */
- mat4_to_axis_angle(buffer + 1, buffer, tmat);
-
- *r_count = 4;
- return buffer;
- }
- else if (strstr(identifier, "scale")) {
- mat4_to_size(buffer, tmat);
-
- *r_count = 3;
- return buffer;
- }
-
- /* as the function hasn't returned yet, read value from system in the default way */
- return setting_get_rna_values(depsgraph, ptr, prop, true, buffer, buffer_size, r_count);
+ BLI_assert(buffer_size >= 4);
+
+ const char *identifier = RNA_property_identifier(prop);
+ float tmat[4][4];
+ int rotmode;
+
+ /* handle for Objects or PoseChannels only
+ * - only Location, Rotation or Scale keyframes are supported currently
+ * - constraints can be on either Objects or PoseChannels, so we only check if the
+ * ptr->type is RNA_Object or RNA_PoseBone, which are the RNA wrapping-info for
+ * those structs, allowing us to identify the owner of the data
+ * - assume that array_index will be sane
+ */
+ if (ptr->type == &RNA_Object) {
+ Object *ob = (Object *)ptr->data;
+ const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+
+ /* Loc code is specific... */
+ if (strstr(identifier, "location")) {
+ copy_v3_v3(buffer, ob_eval->obmat[3]);
+ *r_count = 3;
+ return buffer;
+ }
+
+ copy_m4_m4(tmat, ob_eval->obmat);
+ rotmode = ob_eval->rotmode;
+ }
+ else if (ptr->type == &RNA_PoseBone) {
+ Object *ob = (Object *)ptr->id.data;
+ bPoseChannel *pchan = (bPoseChannel *)ptr->data;
+
+ const Object *ob_eval = DEG_get_evaluated_object(depsgraph, ob);
+ bPoseChannel *pchan_eval = BKE_pose_channel_find_name(ob_eval->pose, pchan->name);
+
+ BKE_armature_mat_pose_to_bone(pchan_eval, pchan_eval->pose_mat, tmat);
+ rotmode = pchan_eval->rotmode;
+
+ /* Loc code is specific... */
+ if (strstr(identifier, "location")) {
+ /* only use for non-connected bones */
+ if ((pchan->bone->parent == NULL) || !(pchan->bone->flag & BONE_CONNECTED)) {
+ copy_v3_v3(buffer, tmat[3]);
+ *r_count = 3;
+ return buffer;
+ }
+ }
+ }
+ else {
+ return setting_get_rna_values(depsgraph, ptr, prop, true, buffer, buffer_size, r_count);
+ }
+
+ /* Rot/Scale code are common! */
+ if (strstr(identifier, "rotation_euler")) {
+ mat4_to_eulO(buffer, rotmode, tmat);
+
+ *r_count = 3;
+ return buffer;
+ }
+ else if (strstr(identifier, "rotation_quaternion")) {
+ float mat3[3][3];
+
+ copy_m3_m4(mat3, tmat);
+ mat3_to_quat_is_ok(buffer, mat3);
+
+ *r_count = 4;
+ return buffer;
+ }
+ else if (strstr(identifier, "rotation_axis_angle")) {
+ /* w = 0, x,y,z = 1,2,3 */
+ mat4_to_axis_angle(buffer + 1, buffer, tmat);
+
+ *r_count = 4;
+ return buffer;
+ }
+ else if (strstr(identifier, "scale")) {
+ mat4_to_size(buffer, tmat);
+
+ *r_count = 3;
+ return buffer;
+ }
+
+ /* as the function hasn't returned yet, read value from system in the default way */
+ return setting_get_rna_values(depsgraph, ptr, prop, true, buffer, buffer_size, r_count);
}
/* ------------------------- Insert Key API ------------------------- */
/* Retrieve current property values to keyframe, possibly applying NLA correction when necessary. */
-static float *get_keyframe_values(
- Depsgraph *depsgraph, ReportList *reports, PointerRNA ptr, PropertyRNA *prop, int index,
- struct NlaKeyframingContext *nla_context, eInsertKeyFlags flag,
- float *buffer, int buffer_size, int *r_count, bool *r_force_all)
+static float *get_keyframe_values(Depsgraph *depsgraph,
+ ReportList *reports,
+ PointerRNA ptr,
+ PropertyRNA *prop,
+ int index,
+ struct NlaKeyframingContext *nla_context,
+ eInsertKeyFlags flag,
+ float *buffer,
+ int buffer_size,
+ int *r_count,
+ bool *r_force_all)
{
- float *values;
-
- if ( (flag & INSERTKEY_MATRIX) &&
- (visualkey_can_use(&ptr, prop)) )
- {
- /* visual-keying is only available for object and pchan datablocks, as
- * it works by keyframing using a value extracted from the final matrix
- * instead of using the kt system to extract a value.
- */
- values = visualkey_get_values(depsgraph, &ptr, prop, buffer, buffer_size, r_count);
- }
- else {
- /* read value from system */
- values = setting_get_rna_values(depsgraph, &ptr, prop, false, buffer, buffer_size, r_count);
- }
-
- /* adjust the value for NLA factors */
- if (!BKE_animsys_nla_remap_keyframe_values(nla_context, &ptr, prop, values, *r_count, index, r_force_all)) {
- BKE_report(reports, RPT_ERROR, "Could not insert keyframe due to zero NLA influence or base value");
-
- if (values != buffer) {
- MEM_freeN(values);
- }
- return NULL;
- }
-
- return values;
+ float *values;
+
+ if ((flag & INSERTKEY_MATRIX) && (visualkey_can_use(&ptr, prop))) {
+ /* visual-keying is only available for object and pchan datablocks, as
+ * it works by keyframing using a value extracted from the final matrix
+ * instead of using the kt system to extract a value.
+ */
+ values = visualkey_get_values(depsgraph, &ptr, prop, buffer, buffer_size, r_count);
+ }
+ else {
+ /* read value from system */
+ values = setting_get_rna_values(depsgraph, &ptr, prop, false, buffer, buffer_size, r_count);
+ }
+
+ /* adjust the value for NLA factors */
+ if (!BKE_animsys_nla_remap_keyframe_values(
+ nla_context, &ptr, prop, values, *r_count, index, r_force_all)) {
+ BKE_report(
+ reports, RPT_ERROR, "Could not insert keyframe due to zero NLA influence or base value");
+
+ if (values != buffer) {
+ MEM_freeN(values);
+ }
+ return NULL;
+ }
+
+ return values;
}
/* Insert the specified keyframe value into a single F-Curve. */
-static bool insert_keyframe_value(ReportList *reports, PointerRNA *ptr, PropertyRNA *prop, FCurve *fcu, float cfra, float curval, eBezTriple_KeyframeType keytype, eInsertKeyFlags flag)
+static bool insert_keyframe_value(ReportList *reports,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ FCurve *fcu,
+ float cfra,
+ float curval,
+ eBezTriple_KeyframeType keytype,
+ eInsertKeyFlags flag)
{
- /* F-Curve not editable? */
- if (fcurve_is_keyframable(fcu) == 0) {
- BKE_reportf(reports, RPT_ERROR,
- "F-Curve with path '%s[%d]' cannot be keyframed, ensure that it is not locked or sampled, "
- "and try removing F-Modifiers",
- fcu->rna_path, fcu->array_index);
- return false;
- }
-
- /* adjust frame on which to add keyframe */
- if ((flag & INSERTKEY_DRIVER) && (fcu->driver)) {
- PathResolvedRNA anim_rna;
-
- if (RNA_path_resolved_create(ptr, prop, fcu->array_index, &anim_rna)) {
- /* for making it easier to add corrective drivers... */
- cfra = evaluate_driver(&anim_rna, fcu->driver, fcu->driver, cfra);
- }
- else {
- cfra = 0.0f;
- }
- }
-
- /* adjust coordinates for cycle aware insertion */
- if (flag & INSERTKEY_CYCLE_AWARE) {
- if (remap_cyclic_keyframe_location(fcu, &cfra, &curval) != FCU_CYCLE_PERFECT) {
- /* inhibit action from insert_vert_fcurve unless it's a perfect cycle */
- flag &= ~INSERTKEY_CYCLE_AWARE;
- }
- }
-
- /* only insert keyframes where they are needed */
- if (flag & INSERTKEY_NEEDED) {
- short insert_mode;
-
- /* check whether this curve really needs a new keyframe */
- insert_mode = new_key_needed(fcu, cfra, curval);
-
- /* only return success if keyframe added */
- if (insert_mode == KEYNEEDED_DONTADD) {
- return false;
- }
-
- /* insert new keyframe at current frame */
- if (insert_vert_fcurve(fcu, cfra, curval, keytype, flag) < 0) {
- return false;
- }
-
- /* delete keyframe immediately before/after newly added */
- switch (insert_mode) {
- case KEYNEEDED_DELPREV:
- delete_fcurve_key(fcu, fcu->totvert - 2, 1);
- break;
- case KEYNEEDED_DELNEXT:
- delete_fcurve_key(fcu, 1, 1);
- break;
- }
-
- return true;
- }
- else {
- /* just insert keyframe */
- return insert_vert_fcurve(fcu, cfra, curval, keytype, flag) >= 0;
- }
+ /* F-Curve not editable? */
+ if (fcurve_is_keyframable(fcu) == 0) {
+ BKE_reportf(
+ reports,
+ RPT_ERROR,
+ "F-Curve with path '%s[%d]' cannot be keyframed, ensure that it is not locked or sampled, "
+ "and try removing F-Modifiers",
+ fcu->rna_path,
+ fcu->array_index);
+ return false;
+ }
+
+ /* adjust frame on which to add keyframe */
+ if ((flag & INSERTKEY_DRIVER) && (fcu->driver)) {
+ PathResolvedRNA anim_rna;
+
+ if (RNA_path_resolved_create(ptr, prop, fcu->array_index, &anim_rna)) {
+ /* for making it easier to add corrective drivers... */
+ cfra = evaluate_driver(&anim_rna, fcu->driver, fcu->driver, cfra);
+ }
+ else {
+ cfra = 0.0f;
+ }
+ }
+
+ /* adjust coordinates for cycle aware insertion */
+ if (flag & INSERTKEY_CYCLE_AWARE) {
+ if (remap_cyclic_keyframe_location(fcu, &cfra, &curval) != FCU_CYCLE_PERFECT) {
+ /* inhibit action from insert_vert_fcurve unless it's a perfect cycle */
+ flag &= ~INSERTKEY_CYCLE_AWARE;
+ }
+ }
+
+ /* only insert keyframes where they are needed */
+ if (flag & INSERTKEY_NEEDED) {
+ short insert_mode;
+
+ /* check whether this curve really needs a new keyframe */
+ insert_mode = new_key_needed(fcu, cfra, curval);
+
+ /* only return success if keyframe added */
+ if (insert_mode == KEYNEEDED_DONTADD) {
+ return false;
+ }
+
+ /* insert new keyframe at current frame */
+ if (insert_vert_fcurve(fcu, cfra, curval, keytype, flag) < 0) {
+ return false;
+ }
+
+ /* delete keyframe immediately before/after newly added */
+ switch (insert_mode) {
+ case KEYNEEDED_DELPREV:
+ delete_fcurve_key(fcu, fcu->totvert - 2, 1);
+ break;
+ case KEYNEEDED_DELNEXT:
+ delete_fcurve_key(fcu, 1, 1);
+ break;
+ }
+
+ return true;
+ }
+ else {
+ /* just insert keyframe */
+ return insert_vert_fcurve(fcu, cfra, curval, keytype, flag) >= 0;
+ }
}
/* Secondary Keyframing API call:
@@ -1105,104 +1157,134 @@ static bool insert_keyframe_value(ReportList *reports, PointerRNA *ptr, Property
* the keyframe insertion. These include the 'visual' keyframing modes, quick refresh,
* and extra keyframe filtering.
*/
-bool insert_keyframe_direct(Depsgraph *depsgraph, ReportList *reports, PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float cfra, eBezTriple_KeyframeType keytype, struct NlaKeyframingContext *nla_context, eInsertKeyFlags flag)
+bool insert_keyframe_direct(Depsgraph *depsgraph,
+ ReportList *reports,
+ PointerRNA ptr,
+ PropertyRNA *prop,
+ FCurve *fcu,
+ float cfra,
+ eBezTriple_KeyframeType keytype,
+ struct NlaKeyframingContext *nla_context,
+ eInsertKeyFlags flag)
{
- float curval = 0.0f;
-
- /* no F-Curve to add keyframe to? */
- if (fcu == NULL) {
- BKE_report(reports, RPT_ERROR, "No F-Curve to add keyframes to");
- return false;
- }
-
- /* if no property given yet, try to validate from F-Curve info */
- if ((ptr.id.data == NULL) && (ptr.data == NULL)) {
- BKE_report(reports, RPT_ERROR, "No RNA pointer available to retrieve values for keyframing from");
- return false;
- }
- if (prop == NULL) {
- PointerRNA tmp_ptr;
-
- /* try to get property we should be affecting */
- if (RNA_path_resolve_property(&ptr, fcu->rna_path, &tmp_ptr, &prop) == false) {
- /* property not found... */
- const char *idname = (ptr.id.data) ? ((ID *)ptr.id.data)->name : TIP_("<No ID pointer>");
-
- BKE_reportf(reports, RPT_ERROR,
- "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
- idname, fcu->rna_path);
- return false;
- }
- else {
- /* property found, so overwrite 'ptr' to make later code easier */
- ptr = tmp_ptr;
- }
- }
-
- /* update F-Curve flags to ensure proper behavior for property type */
- update_autoflags_fcurve_direct(fcu, prop);
-
- /* Obtain the value to insert. */
- float value_buffer[RNA_MAX_ARRAY_LENGTH];
- int value_count;
- int index = fcu->array_index;
-
- float *values = get_keyframe_values(depsgraph, reports, ptr, prop, index, nla_context, flag,
- value_buffer, RNA_MAX_ARRAY_LENGTH, &value_count, NULL);
-
- if (values == NULL) {
- /* This happens if NLA rejects this insertion. */
- return false;
- }
-
- if (index >= 0 && index < value_count) {
- curval = values[index];
- }
-
- if (values != value_buffer) {
- MEM_freeN(values);
- }
-
- return insert_keyframe_value(reports, &ptr, prop, fcu, cfra, curval, keytype, flag);
+ float curval = 0.0f;
+
+ /* no F-Curve to add keyframe to? */
+ if (fcu == NULL) {
+ BKE_report(reports, RPT_ERROR, "No F-Curve to add keyframes to");
+ return false;
+ }
+
+ /* if no property given yet, try to validate from F-Curve info */
+ if ((ptr.id.data == NULL) && (ptr.data == NULL)) {
+ BKE_report(
+ reports, RPT_ERROR, "No RNA pointer available to retrieve values for keyframing from");
+ return false;
+ }
+ if (prop == NULL) {
+ PointerRNA tmp_ptr;
+
+ /* try to get property we should be affecting */
+ if (RNA_path_resolve_property(&ptr, fcu->rna_path, &tmp_ptr, &prop) == false) {
+ /* property not found... */
+ const char *idname = (ptr.id.data) ? ((ID *)ptr.id.data)->name : TIP_("<No ID pointer>");
+
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, "
+ "path = %s)",
+ idname,
+ fcu->rna_path);
+ return false;
+ }
+ else {
+ /* property found, so overwrite 'ptr' to make later code easier */
+ ptr = tmp_ptr;
+ }
+ }
+
+ /* update F-Curve flags to ensure proper behavior for property type */
+ update_autoflags_fcurve_direct(fcu, prop);
+
+ /* Obtain the value to insert. */
+ float value_buffer[RNA_MAX_ARRAY_LENGTH];
+ int value_count;
+ int index = fcu->array_index;
+
+ float *values = get_keyframe_values(depsgraph,
+ reports,
+ ptr,
+ prop,
+ index,
+ nla_context,
+ flag,
+ value_buffer,
+ RNA_MAX_ARRAY_LENGTH,
+ &value_count,
+ NULL);
+
+ if (values == NULL) {
+ /* This happens if NLA rejects this insertion. */
+ return false;
+ }
+
+ if (index >= 0 && index < value_count) {
+ curval = values[index];
+ }
+
+ if (values != value_buffer) {
+ MEM_freeN(values);
+ }
+
+ return insert_keyframe_value(reports, &ptr, prop, fcu, cfra, curval, keytype, flag);
}
/* Find or create the FCurve based on the given path, and insert the specified value into it. */
-static bool insert_keyframe_fcurve_value(
- Main *bmain, ReportList *reports, PointerRNA *ptr, PropertyRNA *prop,
- bAction *act, const char group[], const char rna_path[], int array_index,
- float cfra, float curval, eBezTriple_KeyframeType keytype, eInsertKeyFlags flag)
+static bool insert_keyframe_fcurve_value(Main *bmain,
+ ReportList *reports,
+ PointerRNA *ptr,
+ PropertyRNA *prop,
+ bAction *act,
+ const char group[],
+ const char rna_path[],
+ int array_index,
+ float cfra,
+ float curval,
+ eBezTriple_KeyframeType keytype,
+ eInsertKeyFlags flag)
{
- /* make sure the F-Curve exists
- * - if we're replacing keyframes only, DO NOT create new F-Curves if they do not exist yet
- * but still try to get the F-Curve if it exists...
- */
- FCurve *fcu = verify_fcurve(bmain, act, group, ptr, rna_path, array_index, (flag & INSERTKEY_REPLACE) == 0);
-
- /* we may not have a F-Curve when we're replacing only... */
- if (fcu) {
- /* set color mode if the F-Curve is new (i.e. without any keyframes) */
- if ((fcu->totvert == 0) && (flag & INSERTKEY_XYZ2RGB)) {
- /* for Loc/Rot/Scale and also Color F-Curves, the color of the F-Curve in the Graph Editor,
- * is determined by the array index for the F-Curve
- */
- PropertySubType prop_subtype = RNA_property_subtype(prop);
- if (ELEM(prop_subtype, PROP_TRANSLATION, PROP_XYZ, PROP_EULER, PROP_COLOR, PROP_COORDS)) {
- fcu->color_mode = FCURVE_COLOR_AUTO_RGB;
- }
- else if (ELEM(prop_subtype, PROP_QUATERNION)) {
- fcu->color_mode = FCURVE_COLOR_AUTO_YRGB;
- }
- }
-
- /* update F-Curve flags to ensure proper behavior for property type */
- update_autoflags_fcurve_direct(fcu, prop);
-
- /* insert keyframe */
- return insert_keyframe_value(reports, ptr, prop, fcu, cfra, curval, keytype, flag);
- }
- else {
- return false;
- }
+ /* make sure the F-Curve exists
+ * - if we're replacing keyframes only, DO NOT create new F-Curves if they do not exist yet
+ * but still try to get the F-Curve if it exists...
+ */
+ FCurve *fcu = verify_fcurve(
+ bmain, act, group, ptr, rna_path, array_index, (flag & INSERTKEY_REPLACE) == 0);
+
+ /* we may not have a F-Curve when we're replacing only... */
+ if (fcu) {
+ /* set color mode if the F-Curve is new (i.e. without any keyframes) */
+ if ((fcu->totvert == 0) && (flag & INSERTKEY_XYZ2RGB)) {
+ /* for Loc/Rot/Scale and also Color F-Curves, the color of the F-Curve in the Graph Editor,
+ * is determined by the array index for the F-Curve
+ */
+ PropertySubType prop_subtype = RNA_property_subtype(prop);
+ if (ELEM(prop_subtype, PROP_TRANSLATION, PROP_XYZ, PROP_EULER, PROP_COLOR, PROP_COORDS)) {
+ fcu->color_mode = FCURVE_COLOR_AUTO_RGB;
+ }
+ else if (ELEM(prop_subtype, PROP_QUATERNION)) {
+ fcu->color_mode = FCURVE_COLOR_AUTO_YRGB;
+ }
+ }
+
+ /* update F-Curve flags to ensure proper behavior for property type */
+ update_autoflags_fcurve_direct(fcu, prop);
+
+ /* insert keyframe */
+ return insert_keyframe_value(reports, ptr, prop, fcu, cfra, curval, keytype, flag);
+ }
+ else {
+ return false;
+ }
}
/* Main Keyframing API call:
@@ -1214,119 +1296,188 @@ static bool insert_keyframe_fcurve_value(
*
* index of -1 keys all array indices
*/
-short insert_keyframe(
- Main *bmain, Depsgraph *depsgraph, ReportList *reports, ID *id, bAction *act,
- const char group[], const char rna_path[], int array_index, float cfra, eBezTriple_KeyframeType keytype, ListBase *nla_cache, eInsertKeyFlags flag)
+short insert_keyframe(Main *bmain,
+ Depsgraph *depsgraph,
+ ReportList *reports,
+ ID *id,
+ bAction *act,
+ const char group[],
+ const char rna_path[],
+ int array_index,
+ float cfra,
+ eBezTriple_KeyframeType keytype,
+ ListBase *nla_cache,
+ eInsertKeyFlags flag)
{
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop = NULL;
- AnimData *adt;
- ListBase tmp_nla_cache = {NULL, NULL};
- NlaKeyframingContext *nla_context = NULL;
- int ret = 0;
-
- /* validate pointer first - exit if failure */
- if (id == NULL) {
- BKE_reportf(reports, RPT_ERROR, "No ID block to insert keyframe in (path = %s)", rna_path);
- return 0;
- }
-
- RNA_id_pointer_create(id, &id_ptr);
- if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
- BKE_reportf(reports, RPT_ERROR,
- "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
- (id) ? id->name : TIP_("<Missing ID block>"), rna_path);
- return 0;
- }
-
- /* if no action is provided, keyframe to the default one attached to this ID-block */
- if (act == NULL) {
- /* get action to add F-Curve+keyframe to */
- act = verify_adt_action(bmain, id, 1);
-
- if (act == NULL) {
- BKE_reportf(reports, RPT_ERROR,
- "Could not insert keyframe, as this type does not support animation data (ID = %s, path = %s)",
- id->name, rna_path);
- return 0;
- }
- }
-
- /* apply NLA-mapping to frame to use (if applicable) */
- adt = BKE_animdata_from_id(id);
-
- if (adt && adt->action == act) {
- /* Get NLA context for value remapping. */
- nla_context = BKE_animsys_get_nla_keyframing_context(nla_cache ? nla_cache : &tmp_nla_cache, depsgraph, &id_ptr, adt, cfra);
-
- /* Apply NLA-mapping to frame. */
- cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
- }
-
- /* Obtain values to insert. */
- float value_buffer[RNA_MAX_ARRAY_LENGTH];
- int value_count;
- bool force_all;
-
- float *values = get_keyframe_values(depsgraph, reports, ptr, prop, array_index, nla_context, flag,
- value_buffer, RNA_MAX_ARRAY_LENGTH, &value_count, &force_all);
-
- if (values != NULL) {
- /* Key the entire array. */
- if (array_index == -1 || force_all) {
- /* In force mode, if any of the curves succeeds, drop the replace mode and restart. */
- if (force_all && (flag & INSERTKEY_REPLACE) != 0) {
- int exclude = -1;
-
- for (array_index = 0; array_index < value_count; array_index++) {
- if (insert_keyframe_fcurve_value(bmain, reports, &ptr, prop, act, group, rna_path, array_index, cfra, values[array_index], keytype, flag)) {
- ret++;
- exclude = array_index;
- break;
- }
- }
-
- if (exclude != -1) {
- flag &= ~INSERTKEY_REPLACE;
-
- for (array_index = 0; array_index < value_count; array_index++) {
- if (array_index != exclude) {
- ret += insert_keyframe_fcurve_value(bmain, reports, &ptr, prop, act, group, rna_path, array_index, cfra, values[array_index], keytype, flag);
- }
- }
- }
- }
- /* Simply insert all channels. */
- else {
- for (array_index = 0; array_index < value_count; array_index++) {
- ret += insert_keyframe_fcurve_value(bmain, reports, &ptr, prop, act, group, rna_path, array_index, cfra, values[array_index], keytype, flag);
- }
- }
- }
- /* Key a single index. */
- else {
- if (array_index >= 0 && array_index < value_count) {
- ret += insert_keyframe_fcurve_value(bmain, reports, &ptr, prop, act, group, rna_path, array_index, cfra, values[array_index], keytype, flag);
- }
- }
- }
-
- if (values != value_buffer) {
- MEM_freeN(values);
- }
-
- BKE_animsys_free_nla_keyframing_context_cache(&tmp_nla_cache);
-
- if (ret) {
- if (act != NULL) {
- DEG_id_tag_update(&act->id, ID_RECALC_ANIMATION_NO_FLUSH);
- }
- if (adt != NULL && adt->action != NULL && adt->action != act) {
- DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
- }
- }
-
- return ret;
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop = NULL;
+ AnimData *adt;
+ ListBase tmp_nla_cache = {NULL, NULL};
+ NlaKeyframingContext *nla_context = NULL;
+ int ret = 0;
+
+ /* validate pointer first - exit if failure */
+ if (id == NULL) {
+ BKE_reportf(reports, RPT_ERROR, "No ID block to insert keyframe in (path = %s)", rna_path);
+ return 0;
+ }
+
+ RNA_id_pointer_create(id, &id_ptr);
+ if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
+ BKE_reportf(
+ reports,
+ RPT_ERROR,
+ "Could not insert keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
+ (id) ? id->name : TIP_("<Missing ID block>"),
+ rna_path);
+ return 0;
+ }
+
+ /* if no action is provided, keyframe to the default one attached to this ID-block */
+ if (act == NULL) {
+ /* get action to add F-Curve+keyframe to */
+ act = verify_adt_action(bmain, id, 1);
+
+ if (act == NULL) {
+ BKE_reportf(reports,
+ RPT_ERROR,
+ "Could not insert keyframe, as this type does not support animation data (ID = "
+ "%s, path = %s)",
+ id->name,
+ rna_path);
+ return 0;
+ }
+ }
+
+ /* apply NLA-mapping to frame to use (if applicable) */
+ adt = BKE_animdata_from_id(id);
+
+ if (adt && adt->action == act) {
+ /* Get NLA context for value remapping. */
+ nla_context = BKE_animsys_get_nla_keyframing_context(
+ nla_cache ? nla_cache : &tmp_nla_cache, depsgraph, &id_ptr, adt, cfra);
+
+ /* Apply NLA-mapping to frame. */
+ cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
+ }
+
+ /* Obtain values to insert. */
+ float value_buffer[RNA_MAX_ARRAY_LENGTH];
+ int value_count;
+ bool force_all;
+
+ float *values = get_keyframe_values(depsgraph,
+ reports,
+ ptr,
+ prop,
+ array_index,
+ nla_context,
+ flag,
+ value_buffer,
+ RNA_MAX_ARRAY_LENGTH,
+ &value_count,
+ &force_all);
+
+ if (values != NULL) {
+ /* Key the entire array. */
+ if (array_index == -1 || force_all) {
+ /* In force mode, if any of the curves succeeds, drop the replace mode and restart. */
+ if (force_all && (flag & INSERTKEY_REPLACE) != 0) {
+ int exclude = -1;
+
+ for (array_index = 0; array_index < value_count; array_index++) {
+ if (insert_keyframe_fcurve_value(bmain,
+ reports,
+ &ptr,
+ prop,
+ act,
+ group,
+ rna_path,
+ array_index,
+ cfra,
+ values[array_index],
+ keytype,
+ flag)) {
+ ret++;
+ exclude = array_index;
+ break;
+ }
+ }
+
+ if (exclude != -1) {
+ flag &= ~INSERTKEY_REPLACE;
+
+ for (array_index = 0; array_index < value_count; array_index++) {
+ if (array_index != exclude) {
+ ret += insert_keyframe_fcurve_value(bmain,
+ reports,
+ &ptr,
+ prop,
+ act,
+ group,
+ rna_path,
+ array_index,
+ cfra,
+ values[array_index],
+ keytype,
+ flag);
+ }
+ }
+ }
+ }
+ /* Simply insert all channels. */
+ else {
+ for (array_index = 0; array_index < value_count; array_index++) {
+ ret += insert_keyframe_fcurve_value(bmain,
+ reports,
+ &ptr,
+ prop,
+ act,
+ group,
+ rna_path,
+ array_index,
+ cfra,
+ values[array_index],
+ keytype,
+ flag);
+ }
+ }
+ }
+ /* Key a single index. */
+ else {
+ if (array_index >= 0 && array_index < value_count) {
+ ret += insert_keyframe_fcurve_value(bmain,
+ reports,
+ &ptr,
+ prop,
+ act,
+ group,
+ rna_path,
+ array_index,
+ cfra,
+ values[array_index],
+ keytype,
+ flag);
+ }
+ }
+ }
+
+ if (values != value_buffer) {
+ MEM_freeN(values);
+ }
+
+ BKE_animsys_free_nla_keyframing_context_cache(&tmp_nla_cache);
+
+ if (ret) {
+ if (act != NULL) {
+ DEG_id_tag_update(&act->id, ID_RECALC_ANIMATION_NO_FLUSH);
+ }
+ if (adt != NULL && adt->action != NULL && adt->action != act) {
+ DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
+ }
+ }
+
+ return ret;
}
/* ************************************************** */
@@ -1340,128 +1491,138 @@ short insert_keyframe(
* the keyframe deletion. These include the quick refresh options.
*/
-
-
/**
* \note caller needs to run #BKE_nla_tweakedit_remap to get NLA relative frame.
* caller should also check #BKE_fcurve_is_protected before keying.
*/
static bool delete_keyframe_fcurve(AnimData *adt, FCurve *fcu, float cfra)
{
- bool found;
- int i;
-
- /* try to find index of beztriple to get rid of */
- i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
- if (found) {
- /* delete the key at the index (will sanity check + do recalc afterwards) */
- delete_fcurve_key(fcu, i, 1);
-
- /* Only delete curve too if it won't be doing anything anymore */
- if ((fcu->totvert == 0) && (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0))
- ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
-
- /* return success */
- return true;
- }
- return false;
+ bool found;
+ int i;
+
+ /* try to find index of beztriple to get rid of */
+ i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
+ if (found) {
+ /* delete the key at the index (will sanity check + do recalc afterwards) */
+ delete_fcurve_key(fcu, i, 1);
+
+ /* Only delete curve too if it won't be doing anything anymore */
+ if ((fcu->totvert == 0) &&
+ (list_has_suitable_fmodifier(&fcu->modifiers, 0, FMI_TYPE_GENERATE_CURVE) == 0))
+ ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
+
+ /* return success */
+ return true;
+ }
+ return false;
}
static void deg_tag_after_keyframe_delete(Main *bmain, ID *id, AnimData *adt)
{
- if (adt->action == NULL) {
- /* In the case last f-curve wes removed need to inform dependency graph
- * about relations update, since it needs to get rid of animation operation
- * for this datablock. */
- DEG_id_tag_update_ex(bmain, id, ID_RECALC_ANIMATION_NO_FLUSH);
- DEG_relations_tag_update(bmain);
- }
- else {
- DEG_id_tag_update_ex(bmain, &adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
- }
+ if (adt->action == NULL) {
+ /* In the case last f-curve wes removed need to inform dependency graph
+ * about relations update, since it needs to get rid of animation operation
+ * for this datablock. */
+ DEG_id_tag_update_ex(bmain, id, ID_RECALC_ANIMATION_NO_FLUSH);
+ DEG_relations_tag_update(bmain);
+ }
+ else {
+ DEG_id_tag_update_ex(bmain, &adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
+ }
}
-short delete_keyframe(Main *bmain, ReportList *reports, ID *id, bAction *act,
- const char group[], const char rna_path[], int array_index, float cfra,
+short delete_keyframe(Main *bmain,
+ ReportList *reports,
+ ID *id,
+ bAction *act,
+ const char group[],
+ const char rna_path[],
+ int array_index,
+ float cfra,
eInsertKeyFlags UNUSED(flag))
{
- AnimData *adt = BKE_animdata_from_id(id);
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
- int array_index_max = array_index + 1;
- int ret = 0;
-
- /* sanity checks */
- if (ELEM(NULL, id, adt)) {
- BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from");
- return 0;
- }
-
- /* validate pointer first - exit if failure */
- RNA_id_pointer_create(id, &id_ptr);
- if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
- BKE_reportf(reports, RPT_ERROR,
- "Could not delete keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
- id->name, rna_path);
- return 0;
- }
-
- /* get F-Curve
- * Note: here is one of the places where we don't want new Action + F-Curve added!
- * so 'add' var must be 0
- */
- if (act == NULL) {
- /* if no action is provided, use the default one attached to this ID-block
- * - if it doesn't exist, then we're out of options...
- */
- if (adt->action) {
- act = adt->action;
-
- /* apply NLA-mapping to frame to use (if applicable) */
- cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
- }
- else {
- BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s", id->name);
- return 0;
- }
- }
-
- /* key entire array convenience method */
- if (array_index == -1) {
- array_index = 0;
- array_index_max = RNA_property_array_length(&ptr, prop);
-
- /* for single properties, increase max_index so that the property itself gets included,
- * but don't do this for standard arrays since that can cause corruption issues
- * (extra unused curves)
- */
- if (array_index_max == array_index)
- array_index_max++;
- }
-
- /* will only loop once unless the array index was -1 */
- for (; array_index < array_index_max; array_index++) {
- FCurve *fcu = verify_fcurve(bmain, act, group, &ptr, rna_path, array_index, 0);
-
- /* check if F-Curve exists and/or whether it can be edited */
- if (fcu == NULL)
- continue;
-
- if (BKE_fcurve_is_protected(fcu)) {
- BKE_reportf(reports, RPT_WARNING,
- "Not deleting keyframe for locked F-Curve '%s' for %s '%s'",
- fcu->rna_path, BKE_idcode_to_name(GS(id->name)), id->name + 2);
- continue;
- }
-
- ret += delete_keyframe_fcurve(adt, fcu, cfra);
-
- }
- if (ret) {
- deg_tag_after_keyframe_delete(bmain, id, adt);
- }
- /* return success/failure */
- return ret;
+ AnimData *adt = BKE_animdata_from_id(id);
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ int array_index_max = array_index + 1;
+ int ret = 0;
+
+ /* sanity checks */
+ if (ELEM(NULL, id, adt)) {
+ BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from");
+ return 0;
+ }
+
+ /* validate pointer first - exit if failure */
+ RNA_id_pointer_create(id, &id_ptr);
+ if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
+ BKE_reportf(
+ reports,
+ RPT_ERROR,
+ "Could not delete keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
+ id->name,
+ rna_path);
+ return 0;
+ }
+
+ /* get F-Curve
+ * Note: here is one of the places where we don't want new Action + F-Curve added!
+ * so 'add' var must be 0
+ */
+ if (act == NULL) {
+ /* if no action is provided, use the default one attached to this ID-block
+ * - if it doesn't exist, then we're out of options...
+ */
+ if (adt->action) {
+ act = adt->action;
+
+ /* apply NLA-mapping to frame to use (if applicable) */
+ cfra = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
+ }
+ else {
+ BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s", id->name);
+ return 0;
+ }
+ }
+
+ /* key entire array convenience method */
+ if (array_index == -1) {
+ array_index = 0;
+ array_index_max = RNA_property_array_length(&ptr, prop);
+
+ /* for single properties, increase max_index so that the property itself gets included,
+ * but don't do this for standard arrays since that can cause corruption issues
+ * (extra unused curves)
+ */
+ if (array_index_max == array_index)
+ array_index_max++;
+ }
+
+ /* will only loop once unless the array index was -1 */
+ for (; array_index < array_index_max; array_index++) {
+ FCurve *fcu = verify_fcurve(bmain, act, group, &ptr, rna_path, array_index, 0);
+
+ /* check if F-Curve exists and/or whether it can be edited */
+ if (fcu == NULL)
+ continue;
+
+ if (BKE_fcurve_is_protected(fcu)) {
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Not deleting keyframe for locked F-Curve '%s' for %s '%s'",
+ fcu->rna_path,
+ BKE_idcode_to_name(GS(id->name)),
+ id->name + 2);
+ continue;
+ }
+
+ ret += delete_keyframe_fcurve(adt, fcu, cfra);
+ }
+ if (ret) {
+ deg_tag_after_keyframe_delete(bmain, id, adt);
+ }
+ /* return success/failure */
+ return ret;
}
/* ************************************************** */
@@ -1474,86 +1635,97 @@ short delete_keyframe(Main *bmain, ReportList *reports, ID *id, bAction *act,
* The flag argument is used for special settings that alter the behavior of
* the keyframe deletion. These include the quick refresh options.
*/
-static short clear_keyframe(Main *bmain, ReportList *reports, ID *id, bAction *act,
- const char group[], const char rna_path[], int array_index,
+static short clear_keyframe(Main *bmain,
+ ReportList *reports,
+ ID *id,
+ bAction *act,
+ const char group[],
+ const char rna_path[],
+ int array_index,
eInsertKeyFlags UNUSED(flag))
{
- AnimData *adt = BKE_animdata_from_id(id);
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
- int array_index_max = array_index + 1;
- int ret = 0;
-
- /* sanity checks */
- if (ELEM(NULL, id, adt)) {
- BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from");
- return 0;
- }
-
- /* validate pointer first - exit if failure */
- RNA_id_pointer_create(id, &id_ptr);
- if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
- BKE_reportf(reports, RPT_ERROR,
- "Could not clear keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
- id->name, rna_path);
- return 0;
- }
-
- /* get F-Curve
- * Note: here is one of the places where we don't want new Action + F-Curve added!
- * so 'add' var must be 0
- */
- if (act == NULL) {
- /* if no action is provided, use the default one attached to this ID-block
- * - if it doesn't exist, then we're out of options...
- */
- if (adt->action) {
- act = adt->action;
- }
- else {
- BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s", id->name);
- return 0;
- }
- }
-
- /* key entire array convenience method */
- if (array_index == -1) {
- array_index = 0;
- array_index_max = RNA_property_array_length(&ptr, prop);
-
- /* for single properties, increase max_index so that the property itself gets included,
- * but don't do this for standard arrays since that can cause corruption issues
- * (extra unused curves)
- */
- if (array_index_max == array_index)
- array_index_max++;
- }
-
- /* will only loop once unless the array index was -1 */
- for (; array_index < array_index_max; array_index++) {
- FCurve *fcu = verify_fcurve(bmain, act, group, &ptr, rna_path, array_index, 0);
-
- /* check if F-Curve exists and/or whether it can be edited */
- if (fcu == NULL)
- continue;
-
- if (BKE_fcurve_is_protected(fcu)) {
- BKE_reportf(reports, RPT_WARNING,
- "Not clearing all keyframes from locked F-Curve '%s' for %s '%s'",
- fcu->rna_path, BKE_idcode_to_name(GS(id->name)), id->name + 2);
- continue;
- }
-
- ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
-
- /* return success */
- ret++;
- }
- if (ret) {
- deg_tag_after_keyframe_delete(bmain, id, adt);
- }
- /* return success/failure */
- return ret;
+ AnimData *adt = BKE_animdata_from_id(id);
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+ int array_index_max = array_index + 1;
+ int ret = 0;
+
+ /* sanity checks */
+ if (ELEM(NULL, id, adt)) {
+ BKE_report(reports, RPT_ERROR, "No ID block and/or AnimData to delete keyframe from");
+ return 0;
+ }
+
+ /* validate pointer first - exit if failure */
+ RNA_id_pointer_create(id, &id_ptr);
+ if (RNA_path_resolve_property(&id_ptr, rna_path, &ptr, &prop) == false) {
+ BKE_reportf(
+ reports,
+ RPT_ERROR,
+ "Could not clear keyframe, as RNA path is invalid for the given ID (ID = %s, path = %s)",
+ id->name,
+ rna_path);
+ return 0;
+ }
+
+ /* get F-Curve
+ * Note: here is one of the places where we don't want new Action + F-Curve added!
+ * so 'add' var must be 0
+ */
+ if (act == NULL) {
+ /* if no action is provided, use the default one attached to this ID-block
+ * - if it doesn't exist, then we're out of options...
+ */
+ if (adt->action) {
+ act = adt->action;
+ }
+ else {
+ BKE_reportf(reports, RPT_ERROR, "No action to delete keyframes from for ID = %s", id->name);
+ return 0;
+ }
+ }
+
+ /* key entire array convenience method */
+ if (array_index == -1) {
+ array_index = 0;
+ array_index_max = RNA_property_array_length(&ptr, prop);
+
+ /* for single properties, increase max_index so that the property itself gets included,
+ * but don't do this for standard arrays since that can cause corruption issues
+ * (extra unused curves)
+ */
+ if (array_index_max == array_index)
+ array_index_max++;
+ }
+
+ /* will only loop once unless the array index was -1 */
+ for (; array_index < array_index_max; array_index++) {
+ FCurve *fcu = verify_fcurve(bmain, act, group, &ptr, rna_path, array_index, 0);
+
+ /* check if F-Curve exists and/or whether it can be edited */
+ if (fcu == NULL)
+ continue;
+
+ if (BKE_fcurve_is_protected(fcu)) {
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Not clearing all keyframes from locked F-Curve '%s' for %s '%s'",
+ fcu->rna_path,
+ BKE_idcode_to_name(GS(id->name)),
+ id->name + 2);
+ continue;
+ }
+
+ ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
+
+ /* return success */
+ ret++;
+ }
+ if (ret) {
+ deg_tag_after_keyframe_delete(bmain, id, adt);
+ }
+ /* return success/failure */
+ return ret;
}
/* ******************************************* */
@@ -1561,8 +1733,8 @@ static short clear_keyframe(Main *bmain, ReportList *reports, ID *id, bAction *a
/* mode for commonkey_modifykey */
enum {
- COMMONKEY_MODE_INSERT = 0,
- COMMONKEY_MODE_DELETE,
+ COMMONKEY_MODE_INSERT = 0,
+ COMMONKEY_MODE_DELETE,
} /*eCommonModifyKey_Modes*/;
/* Polling callback for use with ANIM_*_keyframe() operators
@@ -1571,128 +1743,144 @@ enum {
*/
static bool modify_key_op_poll(bContext *C)
{
- ScrArea *sa = CTX_wm_area(C);
- Scene *scene = CTX_data_scene(C);
+ ScrArea *sa = CTX_wm_area(C);
+ Scene *scene = CTX_data_scene(C);
- /* if no area or active scene */
- if (ELEM(NULL, sa, scene))
- return false;
+ /* if no area or active scene */
+ if (ELEM(NULL, sa, scene))
+ return false;
- /* should be fine */
- return true;
+ /* should be fine */
+ return true;
}
/* Insert Key Operator ------------------------ */
static int insert_key_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- Object *obedit = CTX_data_edit_object(C);
- bool ob_edit_mode = false;
-
- float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
- short success;
-
- KeyingSet *ks = keyingset_get_from_op_with_error(op, op->type->prop, scene);
- if (ks == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- /* exit the edit mode to make sure that those object data properties that have been
- * updated since the last switching to the edit mode will be keyframed correctly
- */
- if (obedit && ANIM_keyingset_find_id(ks, (ID *)obedit->data)) {
- ED_object_mode_toggle(C, OB_MODE_EDIT);
- ob_edit_mode = true;
- }
-
- /* try to insert keyframes for the channels specified by KeyingSet */
- success = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
- if (G.debug & G_DEBUG)
- BKE_reportf(op->reports, RPT_INFO, "Keying set '%s' - successfully added %d keyframes", ks->name, success);
-
- /* restore the edit mode if necessary */
- if (ob_edit_mode) {
- ED_object_mode_toggle(C, OB_MODE_EDIT);
- }
-
- /* report failure or do updates? */
- if (success == MODIFYKEY_INVALID_CONTEXT) {
- BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set");
- return OPERATOR_CANCELLED;
- }
- else if (success) {
- /* if the appropriate properties have been set, make a note that we've inserted something */
- if (RNA_boolean_get(op->ptr, "confirm_success"))
- BKE_reportf(op->reports, RPT_INFO, "Successfully added %d keyframes for keying set '%s'", success, ks->name);
-
- /* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
- }
- else
- BKE_report(op->reports, RPT_WARNING, "Keying set failed to insert any keyframes");
-
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ Object *obedit = CTX_data_edit_object(C);
+ bool ob_edit_mode = false;
+
+ float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
+ short success;
+
+ KeyingSet *ks = keyingset_get_from_op_with_error(op, op->type->prop, scene);
+ if (ks == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* exit the edit mode to make sure that those object data properties that have been
+ * updated since the last switching to the edit mode will be keyframed correctly
+ */
+ if (obedit && ANIM_keyingset_find_id(ks, (ID *)obedit->data)) {
+ ED_object_mode_toggle(C, OB_MODE_EDIT);
+ ob_edit_mode = true;
+ }
+
+ /* try to insert keyframes for the channels specified by KeyingSet */
+ success = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_INSERT, cfra);
+ if (G.debug & G_DEBUG)
+ BKE_reportf(op->reports,
+ RPT_INFO,
+ "Keying set '%s' - successfully added %d keyframes",
+ ks->name,
+ success);
+
+ /* restore the edit mode if necessary */
+ if (ob_edit_mode) {
+ ED_object_mode_toggle(C, OB_MODE_EDIT);
+ }
+
+ /* report failure or do updates? */
+ if (success == MODIFYKEY_INVALID_CONTEXT) {
+ BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set");
+ return OPERATOR_CANCELLED;
+ }
+ else if (success) {
+ /* if the appropriate properties have been set, make a note that we've inserted something */
+ if (RNA_boolean_get(op->ptr, "confirm_success"))
+ BKE_reportf(op->reports,
+ RPT_INFO,
+ "Successfully added %d keyframes for keying set '%s'",
+ success,
+ ks->name);
+
+ /* send notifiers that keyframes have been changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
+ }
+ else
+ BKE_report(op->reports, RPT_WARNING, "Keying set failed to insert any keyframes");
+
+ return OPERATOR_FINISHED;
}
void ANIM_OT_keyframe_insert(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Insert Keyframe";
- ot->idname = "ANIM_OT_keyframe_insert";
- ot->description = "Insert keyframes on the current frame for all properties in the specified Keying Set";
-
- /* callbacks */
- ot->exec = insert_key_exec;
- ot->poll = modify_key_op_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* keyingset to use (dynamic enum) */
- prop = RNA_def_enum(ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
- RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
- RNA_def_property_flag(prop, PROP_HIDDEN);
- ot->prop = prop;
-
- /* confirm whether a keyframe was added by showing a popup
- * - by default, this is enabled, since this operator is assumed to be called independently
- */
- prop = RNA_def_boolean(ot->srna, "confirm_success", 1, "Confirm Successful Insert",
- "Show a popup when the keyframes get successfully added");
- RNA_def_property_flag(prop, PROP_HIDDEN);
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Insert Keyframe";
+ ot->idname = "ANIM_OT_keyframe_insert";
+ ot->description =
+ "Insert keyframes on the current frame for all properties in the specified Keying Set";
+
+ /* callbacks */
+ ot->exec = insert_key_exec;
+ ot->poll = modify_key_op_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* keyingset to use (dynamic enum) */
+ prop = RNA_def_enum(
+ ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
+ RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ ot->prop = prop;
+
+ /* confirm whether a keyframe was added by showing a popup
+ * - by default, this is enabled, since this operator is assumed to be called independently
+ */
+ prop = RNA_def_boolean(ot->srna,
+ "confirm_success",
+ 1,
+ "Confirm Successful Insert",
+ "Show a popup when the keyframes get successfully added");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
/* Clone of 'ANIM_OT_keyframe_insert' which uses a name for the keying set instead of an enum. */
void ANIM_OT_keyframe_insert_by_name(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Insert Keyframe (by name)";
- ot->idname = "ANIM_OT_keyframe_insert_by_name";
- ot->description = "Alternate access to 'Insert Keyframe' for keymaps to use";
-
- /* callbacks */
- ot->exec = insert_key_exec;
- ot->poll = modify_key_op_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* keyingset to use (idname) */
- prop = RNA_def_string_file_path(ot->srna, "type", "Type", MAX_ID_NAME - 2, "", "");
- RNA_def_property_flag(prop, PROP_HIDDEN);
- ot->prop = prop;
-
- /* confirm whether a keyframe was added by showing a popup
- * - by default, this is enabled, since this operator is assumed to be called independently
- */
- prop = RNA_def_boolean(ot->srna, "confirm_success", 1, "Confirm Successful Insert",
- "Show a popup when the keyframes get successfully added");
- RNA_def_property_flag(prop, PROP_HIDDEN);
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Insert Keyframe (by name)";
+ ot->idname = "ANIM_OT_keyframe_insert_by_name";
+ ot->description = "Alternate access to 'Insert Keyframe' for keymaps to use";
+
+ /* callbacks */
+ ot->exec = insert_key_exec;
+ ot->poll = modify_key_op_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* keyingset to use (idname) */
+ prop = RNA_def_string_file_path(ot->srna, "type", "Type", MAX_ID_NAME - 2, "", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ ot->prop = prop;
+
+ /* confirm whether a keyframe was added by showing a popup
+ * - by default, this is enabled, since this operator is assumed to be called independently
+ */
+ prop = RNA_def_boolean(ot->srna,
+ "confirm_success",
+ 1,
+ "Confirm Successful Insert",
+ "Show a popup when the keyframes get successfully added");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
/* Insert Key Operator (With Menu) ------------------------ */
@@ -1702,190 +1890,207 @@ void ANIM_OT_keyframe_insert_by_name(wmOperatorType *ot)
static int insert_key_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- Scene *scene = CTX_data_scene(C);
-
- /* if prompting or no active Keying Set, show the menu */
- if ((scene->active_keyingset == 0) || RNA_boolean_get(op->ptr, "always_prompt")) {
- uiPopupMenu *pup;
- uiLayout *layout;
-
- /* call the menu, which will call this operator again, hence the canceled */
- pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
- layout = UI_popup_menu_layout(pup);
- uiItemsEnumO(layout, "ANIM_OT_keyframe_insert_menu", "type");
- UI_popup_menu_end(C, pup);
-
- return OPERATOR_INTERFACE;
- }
- else {
- /* just call the exec() on the active keyingset */
- RNA_enum_set(op->ptr, "type", 0);
- RNA_boolean_set(op->ptr, "confirm_success", true);
-
- return op->type->exec(C, op);
- }
+ Scene *scene = CTX_data_scene(C);
+
+ /* if prompting or no active Keying Set, show the menu */
+ if ((scene->active_keyingset == 0) || RNA_boolean_get(op->ptr, "always_prompt")) {
+ uiPopupMenu *pup;
+ uiLayout *layout;
+
+ /* call the menu, which will call this operator again, hence the canceled */
+ pup = UI_popup_menu_begin(C, RNA_struct_ui_name(op->type->srna), ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
+ uiItemsEnumO(layout, "ANIM_OT_keyframe_insert_menu", "type");
+ UI_popup_menu_end(C, pup);
+
+ return OPERATOR_INTERFACE;
+ }
+ else {
+ /* just call the exec() on the active keyingset */
+ RNA_enum_set(op->ptr, "type", 0);
+ RNA_boolean_set(op->ptr, "confirm_success", true);
+
+ return op->type->exec(C, op);
+ }
}
void ANIM_OT_keyframe_insert_menu(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Insert Keyframe Menu";
- ot->idname = "ANIM_OT_keyframe_insert_menu";
- ot->description = "Insert Keyframes for specified Keying Set, with menu of available Keying Sets if undefined";
-
- /* callbacks */
- ot->invoke = insert_key_menu_invoke;
- ot->exec = insert_key_exec;
- ot->poll = ED_operator_areaactive;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* keyingset to use (dynamic enum) */
- prop = RNA_def_enum(ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
- RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
- RNA_def_property_flag(prop, PROP_HIDDEN);
- ot->prop = prop;
-
- /* confirm whether a keyframe was added by showing a popup
- * - by default, this is disabled so that if a menu is shown, this doesn't come up too
- */
- // XXX should this just be always on?
- prop = RNA_def_boolean(ot->srna, "confirm_success", 0, "Confirm Successful Insert",
- "Show a popup when the keyframes get successfully added");
- RNA_def_property_flag(prop, PROP_HIDDEN);
-
- /* whether the menu should always be shown
- * - by default, the menu should only be shown when there is no active Keying Set (2.5 behavior),
- * although in some cases it might be useful to always shown (pre 2.5 behavior)
- */
- prop = RNA_def_boolean(ot->srna, "always_prompt", 0, "Always Show Menu", "");
- RNA_def_property_flag(prop, PROP_HIDDEN);
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Insert Keyframe Menu";
+ ot->idname = "ANIM_OT_keyframe_insert_menu";
+ ot->description =
+ "Insert Keyframes for specified Keying Set, with menu of available Keying Sets if undefined";
+
+ /* callbacks */
+ ot->invoke = insert_key_menu_invoke;
+ ot->exec = insert_key_exec;
+ ot->poll = ED_operator_areaactive;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* keyingset to use (dynamic enum) */
+ prop = RNA_def_enum(
+ ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
+ RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ ot->prop = prop;
+
+ /* confirm whether a keyframe was added by showing a popup
+ * - by default, this is disabled so that if a menu is shown, this doesn't come up too
+ */
+ // XXX should this just be always on?
+ prop = RNA_def_boolean(ot->srna,
+ "confirm_success",
+ 0,
+ "Confirm Successful Insert",
+ "Show a popup when the keyframes get successfully added");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+
+ /* whether the menu should always be shown
+ * - by default, the menu should only be shown when there is no active Keying Set (2.5 behavior),
+ * although in some cases it might be useful to always shown (pre 2.5 behavior)
+ */
+ prop = RNA_def_boolean(ot->srna, "always_prompt", 0, "Always Show Menu", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
}
/* Delete Key Operator ------------------------ */
static int delete_key_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
- short success;
-
- KeyingSet *ks = keyingset_get_from_op_with_error(op, op->type->prop, scene);
- if (ks == NULL) {
- return OPERATOR_CANCELLED;
- }
-
- const int prop_type = RNA_property_type(op->type->prop);
- if (prop_type == PROP_ENUM) {
- int type = RNA_property_enum_get(op->ptr, op->type->prop);
- ks = ANIM_keyingset_get_from_enum_type(scene, type);
- if (ks == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No active keying set");
- return OPERATOR_CANCELLED;
- }
- }
- else if (prop_type == PROP_STRING) {
- char type_id[MAX_ID_NAME - 2];
- RNA_property_string_get(op->ptr, op->type->prop, type_id);
- ks = ANIM_keyingset_get_from_idname(scene, type_id);
-
- if (ks == NULL) {
- BKE_reportf(op->reports, RPT_ERROR, "No active keying set '%s' not found", type_id);
- return OPERATOR_CANCELLED;
- }
- }
- else {
- BLI_assert(0);
- }
-
- /* report failure */
- if (ks == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No active Keying Set");
- return OPERATOR_CANCELLED;
- }
-
- /* try to delete keyframes for the channels specified by KeyingSet */
- success = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_DELETE, cfra);
- if (G.debug & G_DEBUG)
- printf("KeyingSet '%s' - Successfully removed %d Keyframes\n", ks->name, success);
-
- /* report failure or do updates? */
- if (success == MODIFYKEY_INVALID_CONTEXT) {
- BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set");
- return OPERATOR_CANCELLED;
- }
- else if (success) {
- /* if the appropriate properties have been set, make a note that we've inserted something */
- if (RNA_boolean_get(op->ptr, "confirm_success"))
- BKE_reportf(op->reports, RPT_INFO, "Successfully removed %d keyframes for keying set '%s'", success, ks->name);
-
- /* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
- }
- else
- BKE_report(op->reports, RPT_WARNING, "Keying set failed to remove any keyframes");
-
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
+ short success;
+
+ KeyingSet *ks = keyingset_get_from_op_with_error(op, op->type->prop, scene);
+ if (ks == NULL) {
+ return OPERATOR_CANCELLED;
+ }
+
+ const int prop_type = RNA_property_type(op->type->prop);
+ if (prop_type == PROP_ENUM) {
+ int type = RNA_property_enum_get(op->ptr, op->type->prop);
+ ks = ANIM_keyingset_get_from_enum_type(scene, type);
+ if (ks == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No active keying set");
+ return OPERATOR_CANCELLED;
+ }
+ }
+ else if (prop_type == PROP_STRING) {
+ char type_id[MAX_ID_NAME - 2];
+ RNA_property_string_get(op->ptr, op->type->prop, type_id);
+ ks = ANIM_keyingset_get_from_idname(scene, type_id);
+
+ if (ks == NULL) {
+ BKE_reportf(op->reports, RPT_ERROR, "No active keying set '%s' not found", type_id);
+ return OPERATOR_CANCELLED;
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
+
+ /* report failure */
+ if (ks == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No active Keying Set");
+ return OPERATOR_CANCELLED;
+ }
+
+ /* try to delete keyframes for the channels specified by KeyingSet */
+ success = ANIM_apply_keyingset(C, NULL, NULL, ks, MODIFYKEY_MODE_DELETE, cfra);
+ if (G.debug & G_DEBUG)
+ printf("KeyingSet '%s' - Successfully removed %d Keyframes\n", ks->name, success);
+
+ /* report failure or do updates? */
+ if (success == MODIFYKEY_INVALID_CONTEXT) {
+ BKE_report(op->reports, RPT_ERROR, "No suitable context info for active keying set");
+ return OPERATOR_CANCELLED;
+ }
+ else if (success) {
+ /* if the appropriate properties have been set, make a note that we've inserted something */
+ if (RNA_boolean_get(op->ptr, "confirm_success"))
+ BKE_reportf(op->reports,
+ RPT_INFO,
+ "Successfully removed %d keyframes for keying set '%s'",
+ success,
+ ks->name);
+
+ /* send notifiers that keyframes have been changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
+ }
+ else
+ BKE_report(op->reports, RPT_WARNING, "Keying set failed to remove any keyframes");
+
+ return OPERATOR_FINISHED;
}
void ANIM_OT_keyframe_delete(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Delete Keying-Set Keyframe";
- ot->idname = "ANIM_OT_keyframe_delete";
- ot->description = "Delete keyframes on the current frame for all properties in the specified Keying Set";
-
- /* callbacks */
- ot->exec = delete_key_exec;
- ot->poll = modify_key_op_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* keyingset to use (dynamic enum) */
- prop = RNA_def_enum(ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
- RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
- RNA_def_property_flag(prop, PROP_HIDDEN);
- ot->prop = prop;
-
- /* confirm whether a keyframe was added by showing a popup
- * - by default, this is enabled, since this operator is assumed to be called independently
- */
- RNA_def_boolean(ot->srna, "confirm_success", 1, "Confirm Successful Delete",
- "Show a popup when the keyframes get successfully removed");
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Delete Keying-Set Keyframe";
+ ot->idname = "ANIM_OT_keyframe_delete";
+ ot->description =
+ "Delete keyframes on the current frame for all properties in the specified Keying Set";
+
+ /* callbacks */
+ ot->exec = delete_key_exec;
+ ot->poll = modify_key_op_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* keyingset to use (dynamic enum) */
+ prop = RNA_def_enum(
+ ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
+ RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ ot->prop = prop;
+
+ /* confirm whether a keyframe was added by showing a popup
+ * - by default, this is enabled, since this operator is assumed to be called independently
+ */
+ RNA_def_boolean(ot->srna,
+ "confirm_success",
+ 1,
+ "Confirm Successful Delete",
+ "Show a popup when the keyframes get successfully removed");
}
void ANIM_OT_keyframe_delete_by_name(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Delete Keying-Set Keyframe (by name)";
- ot->idname = "ANIM_OT_keyframe_delete_by_name";
- ot->description = "Alternate access to 'Delete Keyframe' for keymaps to use";
-
- /* callbacks */
- ot->exec = delete_key_exec;
- ot->poll = modify_key_op_poll;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* keyingset to use (idname) */
- prop = RNA_def_string_file_path(ot->srna, "type", "Type", MAX_ID_NAME - 2, "", "");
- RNA_def_property_flag(prop, PROP_HIDDEN);
- ot->prop = prop;
-
- /* confirm whether a keyframe was added by showing a popup
- * - by default, this is enabled, since this operator is assumed to be called independently
- */
- RNA_def_boolean(ot->srna, "confirm_success", 1, "Confirm Successful Delete",
- "Show a popup when the keyframes get successfully removed");
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Delete Keying-Set Keyframe (by name)";
+ ot->idname = "ANIM_OT_keyframe_delete_by_name";
+ ot->description = "Alternate access to 'Delete Keyframe' for keymaps to use";
+
+ /* callbacks */
+ ot->exec = delete_key_exec;
+ ot->poll = modify_key_op_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* keyingset to use (idname) */
+ prop = RNA_def_string_file_path(ot->srna, "type", "Type", MAX_ID_NAME - 2, "", "");
+ RNA_def_property_flag(prop, PROP_HIDDEN);
+ ot->prop = prop;
+
+ /* confirm whether a keyframe was added by showing a popup
+ * - by default, this is enabled, since this operator is assumed to be called independently
+ */
+ RNA_def_boolean(ot->srna,
+ "confirm_success",
+ 1,
+ "Confirm Successful Delete",
+ "Show a popup when the keyframes get successfully removed");
}
/* Delete Key Operator ------------------------ */
@@ -1895,503 +2100,533 @@ void ANIM_OT_keyframe_delete_by_name(wmOperatorType *ot)
static int clear_anim_v3d_exec(bContext *C, wmOperator *UNUSED(op))
{
- bool changed = false;
-
- CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
- {
- /* just those in active action... */
- if ((ob->adt) && (ob->adt->action)) {
- AnimData *adt = ob->adt;
- bAction *act = adt->action;
- FCurve *fcu, *fcn;
-
- for (fcu = act->curves.first; fcu; fcu = fcn) {
- bool can_delete = false;
-
- fcn = fcu->next;
-
- /* in pose mode, only delete the F-Curve if it belongs to a selected bone */
- if (ob->mode & OB_MODE_POSE) {
- if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones[")) {
- bPoseChannel *pchan;
- char *bone_name;
-
- /* get bone-name, and check if this bone is selected */
- bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
- pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
- if (bone_name) MEM_freeN(bone_name);
-
- /* delete if bone is selected*/
- if ((pchan) && (pchan->bone)) {
- if (pchan->bone->flag & BONE_SELECTED)
- can_delete = true;
- }
- }
- }
- else {
- /* object mode - all of Object's F-Curves are affected */
- can_delete = true;
- }
-
- /* delete F-Curve completely */
- if (can_delete) {
- ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
- DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
- changed = true;
- }
- }
- }
- }
- CTX_DATA_END;
-
- if (!changed) {
- return OPERATOR_CANCELLED;
- }
-
- /* send updates */
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
-
- return OPERATOR_FINISHED;
+ bool changed = false;
+
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
+ /* just those in active action... */
+ if ((ob->adt) && (ob->adt->action)) {
+ AnimData *adt = ob->adt;
+ bAction *act = adt->action;
+ FCurve *fcu, *fcn;
+
+ for (fcu = act->curves.first; fcu; fcu = fcn) {
+ bool can_delete = false;
+
+ fcn = fcu->next;
+
+ /* in pose mode, only delete the F-Curve if it belongs to a selected bone */
+ if (ob->mode & OB_MODE_POSE) {
+ if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones[")) {
+ bPoseChannel *pchan;
+ char *bone_name;
+
+ /* get bone-name, and check if this bone is selected */
+ bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
+ pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
+ if (bone_name)
+ MEM_freeN(bone_name);
+
+ /* delete if bone is selected*/
+ if ((pchan) && (pchan->bone)) {
+ if (pchan->bone->flag & BONE_SELECTED)
+ can_delete = true;
+ }
+ }
+ }
+ else {
+ /* object mode - all of Object's F-Curves are affected */
+ can_delete = true;
+ }
+
+ /* delete F-Curve completely */
+ if (can_delete) {
+ ANIM_fcurve_delete_from_animdata(NULL, adt, fcu);
+ DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
+ changed = true;
+ }
+ }
+ }
+ }
+ CTX_DATA_END;
+
+ if (!changed) {
+ return OPERATOR_CANCELLED;
+ }
+
+ /* send updates */
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
+
+ return OPERATOR_FINISHED;
}
void ANIM_OT_keyframe_clear_v3d(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Animation";
- ot->description = "Remove all keyframe animation for selected objects";
- ot->idname = "ANIM_OT_keyframe_clear_v3d";
+ /* identifiers */
+ ot->name = "Remove Animation";
+ ot->description = "Remove all keyframe animation for selected objects";
+ ot->idname = "ANIM_OT_keyframe_clear_v3d";
- /* callbacks */
- ot->invoke = WM_operator_confirm;
- ot->exec = clear_anim_v3d_exec;
+ /* callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = clear_anim_v3d_exec;
- ot->poll = ED_operator_areaactive;
+ ot->poll = ED_operator_areaactive;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
static int delete_key_v3d_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- float cfra = (float)CFRA;
-
- CTX_DATA_BEGIN (C, Object *, ob, selected_objects)
- {
- ID *id = &ob->id;
- int success = 0;
-
- /* just those in active action... */
- if ((ob->adt) && (ob->adt->action)) {
- AnimData *adt = ob->adt;
- bAction *act = adt->action;
- FCurve *fcu, *fcn;
- const float cfra_unmap = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
-
- for (fcu = act->curves.first; fcu; fcu = fcn) {
- fcn = fcu->next;
-
- /* don't touch protected F-Curves */
- if (BKE_fcurve_is_protected(fcu)) {
- BKE_reportf(op->reports, RPT_WARNING,
- "Not deleting keyframe for locked F-Curve '%s', object '%s'",
- fcu->rna_path, id->name + 2);
- continue;
- }
-
- /* special exception for bones, as this makes this operator more convenient to use
- * NOTE: This is only done in pose mode. In object mode, we're dealing with the entire object.
- */
- if ((ob->mode & OB_MODE_POSE) && strstr(fcu->rna_path, "pose.bones[\"")) {
- bPoseChannel *pchan;
- char *bone_name;
-
- /* get bone-name, and check if this bone is selected */
- bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
- pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
- if (bone_name) MEM_freeN(bone_name);
-
- /* skip if bone is not selected */
- if ((pchan) && (pchan->bone)) {
- /* bones are only selected/editable if visible... */
- bArmature *arm = (bArmature *)ob->data;
-
- /* skipping - not visible on currently visible layers */
- if ((arm->layer & pchan->bone->layer) == 0)
- continue;
- /* skipping - is currently hidden */
- if (pchan->bone->flag & BONE_HIDDEN_P)
- continue;
-
- /* selection flag... */
- if ((pchan->bone->flag & BONE_SELECTED) == 0)
- continue;
- }
- }
-
- /* delete keyframes on current frame
- * WARNING: this can delete the next F-Curve, hence the "fcn" copying
- */
- success += delete_keyframe_fcurve(adt, fcu, cfra_unmap);
- }
- DEG_id_tag_update(&ob->adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
- }
-
- /* report success (or failure) */
- if (success)
- BKE_reportf(op->reports, RPT_INFO, "Object '%s' successfully had %d keyframes removed", id->name + 2, success);
- else
- BKE_reportf(op->reports, RPT_ERROR, "No keyframes removed from Object '%s'", id->name + 2);
-
- DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
- }
- CTX_DATA_END;
-
- /* send updates */
- WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
-
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ float cfra = (float)CFRA;
+
+ CTX_DATA_BEGIN (C, Object *, ob, selected_objects) {
+ ID *id = &ob->id;
+ int success = 0;
+
+ /* just those in active action... */
+ if ((ob->adt) && (ob->adt->action)) {
+ AnimData *adt = ob->adt;
+ bAction *act = adt->action;
+ FCurve *fcu, *fcn;
+ const float cfra_unmap = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
+
+ for (fcu = act->curves.first; fcu; fcu = fcn) {
+ fcn = fcu->next;
+
+ /* don't touch protected F-Curves */
+ if (BKE_fcurve_is_protected(fcu)) {
+ BKE_reportf(op->reports,
+ RPT_WARNING,
+ "Not deleting keyframe for locked F-Curve '%s', object '%s'",
+ fcu->rna_path,
+ id->name + 2);
+ continue;
+ }
+
+ /* special exception for bones, as this makes this operator more convenient to use
+ * NOTE: This is only done in pose mode. In object mode, we're dealing with the entire object.
+ */
+ if ((ob->mode & OB_MODE_POSE) && strstr(fcu->rna_path, "pose.bones[\"")) {
+ bPoseChannel *pchan;
+ char *bone_name;
+
+ /* get bone-name, and check if this bone is selected */
+ bone_name = BLI_str_quoted_substrN(fcu->rna_path, "pose.bones[");
+ pchan = BKE_pose_channel_find_name(ob->pose, bone_name);
+ if (bone_name)
+ MEM_freeN(bone_name);
+
+ /* skip if bone is not selected */
+ if ((pchan) && (pchan->bone)) {
+ /* bones are only selected/editable if visible... */
+ bArmature *arm = (bArmature *)ob->data;
+
+ /* skipping - not visible on currently visible layers */
+ if ((arm->layer & pchan->bone->layer) == 0)
+ continue;
+ /* skipping - is currently hidden */
+ if (pchan->bone->flag & BONE_HIDDEN_P)
+ continue;
+
+ /* selection flag... */
+ if ((pchan->bone->flag & BONE_SELECTED) == 0)
+ continue;
+ }
+ }
+
+ /* delete keyframes on current frame
+ * WARNING: this can delete the next F-Curve, hence the "fcn" copying
+ */
+ success += delete_keyframe_fcurve(adt, fcu, cfra_unmap);
+ }
+ DEG_id_tag_update(&ob->adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
+ }
+
+ /* report success (or failure) */
+ if (success)
+ BKE_reportf(op->reports,
+ RPT_INFO,
+ "Object '%s' successfully had %d keyframes removed",
+ id->name + 2,
+ success);
+ else
+ BKE_reportf(op->reports, RPT_ERROR, "No keyframes removed from Object '%s'", id->name + 2);
+
+ DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM);
+ }
+ CTX_DATA_END;
+
+ /* send updates */
+ WM_event_add_notifier(C, NC_OBJECT | ND_KEYS, NULL);
+
+ return OPERATOR_FINISHED;
}
void ANIM_OT_keyframe_delete_v3d(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Delete Keyframe";
- ot->description = "Remove keyframes on current frame for selected objects and bones";
- ot->idname = "ANIM_OT_keyframe_delete_v3d";
+ /* identifiers */
+ ot->name = "Delete Keyframe";
+ ot->description = "Remove keyframes on current frame for selected objects and bones";
+ ot->idname = "ANIM_OT_keyframe_delete_v3d";
- /* callbacks */
- ot->invoke = WM_operator_confirm;
- ot->exec = delete_key_v3d_exec;
+ /* callbacks */
+ ot->invoke = WM_operator_confirm;
+ ot->exec = delete_key_v3d_exec;
- ot->poll = ED_operator_areaactive;
+ ot->poll = ED_operator_areaactive;
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
-
/* Insert Key Button Operator ------------------------ */
static int insert_key_button_exec(bContext *C, wmOperator *op)
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ToolSettings *ts = scene->toolsettings;
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
- char *path;
- uiBut *but;
- float cfra = (float)CFRA;
- short success = 0;
- int index;
- const bool all = RNA_boolean_get(op->ptr, "all");
- eInsertKeyFlags flag = INSERTKEY_NOFLAGS;
-
-
- /* flags for inserting keyframes */
- flag = ANIM_get_keyframing_flags(scene, 1);
-
- /* try to insert keyframe using property retrieved from UI */
- if (!(but = UI_context_active_but_prop_get(C, &ptr, &prop, &index))) {
- /* pass event on if no active button found */
- return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
- }
-
- if ((ptr.id.data && ptr.data && prop) && RNA_property_animateable(&ptr, prop)) {
- if (ptr.type == &RNA_NlaStrip) {
- /* Handle special properties for NLA Strips, whose F-Curves are stored on the
- * strips themselves. These are stored separately or else the properties will
- * not have any effect.
- */
- NlaStrip *strip = (NlaStrip *)ptr.data;
- FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), index);
-
- if (fcu) {
- success = insert_keyframe_direct(depsgraph, op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, 0);
- }
- else {
- BKE_report(op->reports, RPT_ERROR,
- "This property cannot be animated as it will not get updated correctly");
- }
- }
- else if (UI_but_flag_is_set(but, UI_BUT_DRIVEN)) {
- /* Driven property - Find driver */
- FCurve *fcu;
- bool driven, special;
-
- fcu = rna_get_fcurve_context_ui(C, &ptr, prop, index, NULL, NULL, &driven, &special);
-
- if (fcu && driven) {
- success = insert_keyframe_direct(depsgraph, op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, INSERTKEY_DRIVER);
- }
- }
- else {
- /* standard properties */
- path = RNA_path_from_ID_to_property(&ptr, prop);
-
- if (path) {
- const char *identifier = RNA_property_identifier(prop);
- const char *group = NULL;
-
- /* Special exception for keyframing transforms:
- * Set "group" for this manually, instead of having them appearing at the bottom (ungrouped)
- * part of the channels list. Leaving these ungrouped is not a nice user behavior in this case.
- *
- * TODO: Perhaps we can extend this behavior in future for other properties...
- */
- if (ptr.type == &RNA_PoseBone) {
- bPoseChannel *pchan = (bPoseChannel *)ptr.data;
- group = pchan->name;
- }
- else if ((ptr.type == &RNA_Object) &&
- (strstr(identifier, "location") || strstr(identifier, "rotation") || strstr(identifier, "scale")))
- {
- /* NOTE: Keep this label in sync with the "ID" case in
- * keyingsets_utils.py :: get_transform_generators_base_info()
- */
- group = "Object Transforms";
- }
-
-
- if (all) {
- /* -1 indicates operating on the entire array (or the property itself otherwise) */
- index = -1;
- }
-
- success = insert_keyframe(bmain, depsgraph, op->reports, ptr.id.data, NULL, group, path, index, cfra, ts->keyframe_type, NULL, flag);
-
- MEM_freeN(path);
- }
- else {
- BKE_report(op->reports, RPT_WARNING,
- "Failed to resolve path to property, "
- "try manually specifying this using a Keying Set instead");
- }
- }
- }
- else {
- if (prop && !RNA_property_animateable(&ptr, prop)) {
- BKE_reportf(op->reports, RPT_WARNING,
- "\"%s\" property cannot be animated",
- RNA_property_identifier(prop));
- }
- else {
- BKE_reportf(op->reports, RPT_WARNING,
- "Button doesn't appear to have any property information attached (ptr.data = %p, prop = %p)",
- (void *)ptr.data, (void *)prop);
- }
- }
-
- if (success) {
- ID *id = ptr.id.data;
- AnimData *adt = BKE_animdata_from_id(id);
- if (adt->action != NULL) {
- DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
- }
- DEG_id_tag_update(id, ID_RECALC_ANIMATION_NO_FLUSH);
-
- /* send updates */
- UI_context_update_anim_flag(C);
-
- /* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
- }
-
- return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ToolSettings *ts = scene->toolsettings;
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ char *path;
+ uiBut *but;
+ float cfra = (float)CFRA;
+ short success = 0;
+ int index;
+ const bool all = RNA_boolean_get(op->ptr, "all");
+ eInsertKeyFlags flag = INSERTKEY_NOFLAGS;
+
+ /* flags for inserting keyframes */
+ flag = ANIM_get_keyframing_flags(scene, 1);
+
+ /* try to insert keyframe using property retrieved from UI */
+ if (!(but = UI_context_active_but_prop_get(C, &ptr, &prop, &index))) {
+ /* pass event on if no active button found */
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ if ((ptr.id.data && ptr.data && prop) && RNA_property_animateable(&ptr, prop)) {
+ if (ptr.type == &RNA_NlaStrip) {
+ /* Handle special properties for NLA Strips, whose F-Curves are stored on the
+ * strips themselves. These are stored separately or else the properties will
+ * not have any effect.
+ */
+ NlaStrip *strip = (NlaStrip *)ptr.data;
+ FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), index);
+
+ if (fcu) {
+ success = insert_keyframe_direct(
+ depsgraph, op->reports, ptr, prop, fcu, cfra, ts->keyframe_type, NULL, 0);
+ }
+ else {
+ BKE_report(op->reports,
+ RPT_ERROR,
+ "This property cannot be animated as it will not get updated correctly");
+ }
+ }
+ else if (UI_but_flag_is_set(but, UI_BUT_DRIVEN)) {
+ /* Driven property - Find driver */
+ FCurve *fcu;
+ bool driven, special;
+
+ fcu = rna_get_fcurve_context_ui(C, &ptr, prop, index, NULL, NULL, &driven, &special);
+
+ if (fcu && driven) {
+ success = insert_keyframe_direct(depsgraph,
+ op->reports,
+ ptr,
+ prop,
+ fcu,
+ cfra,
+ ts->keyframe_type,
+ NULL,
+ INSERTKEY_DRIVER);
+ }
+ }
+ else {
+ /* standard properties */
+ path = RNA_path_from_ID_to_property(&ptr, prop);
+
+ if (path) {
+ const char *identifier = RNA_property_identifier(prop);
+ const char *group = NULL;
+
+ /* Special exception for keyframing transforms:
+ * Set "group" for this manually, instead of having them appearing at the bottom (ungrouped)
+ * part of the channels list. Leaving these ungrouped is not a nice user behavior in this case.
+ *
+ * TODO: Perhaps we can extend this behavior in future for other properties...
+ */
+ if (ptr.type == &RNA_PoseBone) {
+ bPoseChannel *pchan = (bPoseChannel *)ptr.data;
+ group = pchan->name;
+ }
+ else if ((ptr.type == &RNA_Object) &&
+ (strstr(identifier, "location") || strstr(identifier, "rotation") ||
+ strstr(identifier, "scale"))) {
+ /* NOTE: Keep this label in sync with the "ID" case in
+ * keyingsets_utils.py :: get_transform_generators_base_info()
+ */
+ group = "Object Transforms";
+ }
+
+ if (all) {
+ /* -1 indicates operating on the entire array (or the property itself otherwise) */
+ index = -1;
+ }
+
+ success = insert_keyframe(bmain,
+ depsgraph,
+ op->reports,
+ ptr.id.data,
+ NULL,
+ group,
+ path,
+ index,
+ cfra,
+ ts->keyframe_type,
+ NULL,
+ flag);
+
+ MEM_freeN(path);
+ }
+ else {
+ BKE_report(op->reports,
+ RPT_WARNING,
+ "Failed to resolve path to property, "
+ "try manually specifying this using a Keying Set instead");
+ }
+ }
+ }
+ else {
+ if (prop && !RNA_property_animateable(&ptr, prop)) {
+ BKE_reportf(op->reports,
+ RPT_WARNING,
+ "\"%s\" property cannot be animated",
+ RNA_property_identifier(prop));
+ }
+ else {
+ BKE_reportf(op->reports,
+ RPT_WARNING,
+ "Button doesn't appear to have any property information attached (ptr.data = "
+ "%p, prop = %p)",
+ (void *)ptr.data,
+ (void *)prop);
+ }
+ }
+
+ if (success) {
+ ID *id = ptr.id.data;
+ AnimData *adt = BKE_animdata_from_id(id);
+ if (adt->action != NULL) {
+ DEG_id_tag_update(&adt->action->id, ID_RECALC_ANIMATION_NO_FLUSH);
+ }
+ DEG_id_tag_update(id, ID_RECALC_ANIMATION_NO_FLUSH);
+
+ /* send updates */
+ UI_context_update_anim_flag(C);
+
+ /* send notifiers that keyframes have been changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
+ }
+
+ return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void ANIM_OT_keyframe_insert_button(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Insert Keyframe (Buttons)";
- ot->idname = "ANIM_OT_keyframe_insert_button";
- ot->description = "Insert a keyframe for current UI-active property";
+ /* identifiers */
+ ot->name = "Insert Keyframe (Buttons)";
+ ot->idname = "ANIM_OT_keyframe_insert_button";
+ ot->description = "Insert a keyframe for current UI-active property";
- /* callbacks */
- ot->exec = insert_key_button_exec;
- ot->poll = modify_key_op_poll;
+ /* callbacks */
+ ot->exec = insert_key_button_exec;
+ ot->poll = modify_key_op_poll;
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
- /* properties */
- RNA_def_boolean(ot->srna, "all", 1, "All", "Insert a keyframe for all element of the array");
+ /* properties */
+ RNA_def_boolean(ot->srna, "all", 1, "All", "Insert a keyframe for all element of the array");
}
/* Delete Key Button Operator ------------------------ */
static int delete_key_button_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
- Main *bmain = CTX_data_main(C);
- char *path;
- float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
- short success = 0;
- int index;
- const bool all = RNA_boolean_get(op->ptr, "all");
-
- /* try to insert keyframe using property retrieved from UI */
- if (!UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
- /* pass event on if no active button found */
- return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
- }
-
- if (ptr.id.data && ptr.data && prop) {
- if (BKE_nlastrip_has_curves_for_property(&ptr, prop)) {
- /* Handle special properties for NLA Strips, whose F-Curves are stored on the
- * strips themselves. These are stored separately or else the properties will
- * not have any effect.
- */
- ID *id = ptr.id.data;
- NlaStrip *strip = (NlaStrip *)ptr.data;
- FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), 0);
-
- if (fcu) {
- if (BKE_fcurve_is_protected(fcu)) {
- BKE_reportf(op->reports, RPT_WARNING,
- "Not deleting keyframe for locked F-Curve for NLA Strip influence on %s - %s '%s'",
- strip->name, BKE_idcode_to_name(GS(id->name)), id->name + 2);
- }
- else {
- /* remove the keyframe directly
- * NOTE: cannot use delete_keyframe_fcurve(), as that will free the curve,
- * and delete_keyframe() expects the FCurve to be part of an action
- */
- bool found = false;
- int i;
-
- /* try to find index of beztriple to get rid of */
- i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
- if (found) {
- /* delete the key at the index (will sanity check + do recalc afterwards) */
- delete_fcurve_key(fcu, i, 1);
- success = true;
- }
- }
- }
- }
- else {
- /* standard properties */
- path = RNA_path_from_ID_to_property(&ptr, prop);
-
- if (path) {
- if (all) {
- /* -1 indicates operating on the entire array (or the property itself otherwise) */
- index = -1;
- }
-
- success = delete_keyframe(bmain, op->reports, ptr.id.data, NULL, NULL, path, index, cfra, 0);
- MEM_freeN(path);
- }
- else if (G.debug & G_DEBUG)
- printf("Button Delete-Key: no path to property\n");
- }
- }
- else if (G.debug & G_DEBUG) {
- printf("ptr.data = %p, prop = %p\n", (void *)ptr.data, (void *)prop);
- }
-
-
- if (success) {
- /* send updates */
- UI_context_update_anim_flag(C);
-
- /* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
- }
-
- return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ Scene *scene = CTX_data_scene(C);
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ Main *bmain = CTX_data_main(C);
+ char *path;
+ float cfra = (float)CFRA; // XXX for now, don't bother about all the yucky offset crap
+ short success = 0;
+ int index;
+ const bool all = RNA_boolean_get(op->ptr, "all");
+
+ /* try to insert keyframe using property retrieved from UI */
+ if (!UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
+ /* pass event on if no active button found */
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ if (ptr.id.data && ptr.data && prop) {
+ if (BKE_nlastrip_has_curves_for_property(&ptr, prop)) {
+ /* Handle special properties for NLA Strips, whose F-Curves are stored on the
+ * strips themselves. These are stored separately or else the properties will
+ * not have any effect.
+ */
+ ID *id = ptr.id.data;
+ NlaStrip *strip = (NlaStrip *)ptr.data;
+ FCurve *fcu = list_find_fcurve(&strip->fcurves, RNA_property_identifier(prop), 0);
+
+ if (fcu) {
+ if (BKE_fcurve_is_protected(fcu)) {
+ BKE_reportf(
+ op->reports,
+ RPT_WARNING,
+ "Not deleting keyframe for locked F-Curve for NLA Strip influence on %s - %s '%s'",
+ strip->name,
+ BKE_idcode_to_name(GS(id->name)),
+ id->name + 2);
+ }
+ else {
+ /* remove the keyframe directly
+ * NOTE: cannot use delete_keyframe_fcurve(), as that will free the curve,
+ * and delete_keyframe() expects the FCurve to be part of an action
+ */
+ bool found = false;
+ int i;
+
+ /* try to find index of beztriple to get rid of */
+ i = binarysearch_bezt_index(fcu->bezt, cfra, fcu->totvert, &found);
+ if (found) {
+ /* delete the key at the index (will sanity check + do recalc afterwards) */
+ delete_fcurve_key(fcu, i, 1);
+ success = true;
+ }
+ }
+ }
+ }
+ else {
+ /* standard properties */
+ path = RNA_path_from_ID_to_property(&ptr, prop);
+
+ if (path) {
+ if (all) {
+ /* -1 indicates operating on the entire array (or the property itself otherwise) */
+ index = -1;
+ }
+
+ success = delete_keyframe(
+ bmain, op->reports, ptr.id.data, NULL, NULL, path, index, cfra, 0);
+ MEM_freeN(path);
+ }
+ else if (G.debug & G_DEBUG)
+ printf("Button Delete-Key: no path to property\n");
+ }
+ }
+ else if (G.debug & G_DEBUG) {
+ printf("ptr.data = %p, prop = %p\n", (void *)ptr.data, (void *)prop);
+ }
+
+ if (success) {
+ /* send updates */
+ UI_context_update_anim_flag(C);
+
+ /* send notifiers that keyframes have been changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
+ }
+
+ return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void ANIM_OT_keyframe_delete_button(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Delete Keyframe (Buttons)";
- ot->idname = "ANIM_OT_keyframe_delete_button";
- ot->description = "Delete current keyframe of current UI-active property";
+ /* identifiers */
+ ot->name = "Delete Keyframe (Buttons)";
+ ot->idname = "ANIM_OT_keyframe_delete_button";
+ ot->description = "Delete current keyframe of current UI-active property";
- /* callbacks */
- ot->exec = delete_key_button_exec;
- ot->poll = modify_key_op_poll;
+ /* callbacks */
+ ot->exec = delete_key_button_exec;
+ ot->poll = modify_key_op_poll;
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
- /* properties */
- RNA_def_boolean(ot->srna, "all", 1, "All", "Delete keyframes from all elements of the array");
+ /* properties */
+ RNA_def_boolean(ot->srna, "all", 1, "All", "Delete keyframes from all elements of the array");
}
-
/* Clear Key Button Operator ------------------------ */
static int clear_key_button_exec(bContext *C, wmOperator *op)
{
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
- Main *bmain = CTX_data_main(C);
- char *path;
- short success = 0;
- int index;
- const bool all = RNA_boolean_get(op->ptr, "all");
-
- /* try to insert keyframe using property retrieved from UI */
- if (!UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
- /* pass event on if no active button found */
- return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
- }
-
- if (ptr.id.data && ptr.data && prop) {
- path = RNA_path_from_ID_to_property(&ptr, prop);
-
- if (path) {
- if (all) {
- /* -1 indicates operating on the entire array (or the property itself otherwise) */
- index = -1;
- }
-
- success += clear_keyframe(bmain, op->reports, ptr.id.data, NULL, NULL, path, index, 0);
- MEM_freeN(path);
- }
- else if (G.debug & G_DEBUG)
- printf("Button Clear-Key: no path to property\n");
- }
- else if (G.debug & G_DEBUG) {
- printf("ptr.data = %p, prop = %p\n", (void *)ptr.data, (void *)prop);
- }
-
-
- if (success) {
- /* send updates */
- UI_context_update_anim_flag(C);
-
- /* send notifiers that keyframes have been changed */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
- }
-
- return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ Main *bmain = CTX_data_main(C);
+ char *path;
+ short success = 0;
+ int index;
+ const bool all = RNA_boolean_get(op->ptr, "all");
+
+ /* try to insert keyframe using property retrieved from UI */
+ if (!UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
+ /* pass event on if no active button found */
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ if (ptr.id.data && ptr.data && prop) {
+ path = RNA_path_from_ID_to_property(&ptr, prop);
+
+ if (path) {
+ if (all) {
+ /* -1 indicates operating on the entire array (or the property itself otherwise) */
+ index = -1;
+ }
+
+ success += clear_keyframe(bmain, op->reports, ptr.id.data, NULL, NULL, path, index, 0);
+ MEM_freeN(path);
+ }
+ else if (G.debug & G_DEBUG)
+ printf("Button Clear-Key: no path to property\n");
+ }
+ else if (G.debug & G_DEBUG) {
+ printf("ptr.data = %p, prop = %p\n", (void *)ptr.data, (void *)prop);
+ }
+
+ if (success) {
+ /* send updates */
+ UI_context_update_anim_flag(C);
+
+ /* send notifiers that keyframes have been changed */
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_REMOVED, NULL);
+ }
+
+ return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void ANIM_OT_keyframe_clear_button(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Clear Keyframe (Buttons)";
- ot->idname = "ANIM_OT_keyframe_clear_button";
- ot->description = "Clear all keyframes on the currently active property";
+ /* identifiers */
+ ot->name = "Clear Keyframe (Buttons)";
+ ot->idname = "ANIM_OT_keyframe_clear_button";
+ ot->description = "Clear all keyframes on the currently active property";
- /* callbacks */
- ot->exec = clear_key_button_exec;
- ot->poll = modify_key_op_poll;
+ /* callbacks */
+ ot->exec = clear_key_button_exec;
+ ot->poll = modify_key_op_poll;
- /* flags */
- ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
+ /* flags */
+ ot->flag = OPTYPE_UNDO | OPTYPE_INTERNAL;
- /* properties */
- RNA_def_boolean(ot->srna, "all", 1, "All", "Clear keyframes from all elements of the array");
+ /* properties */
+ RNA_def_boolean(ot->srna, "all", 1, "All", "Clear keyframes from all elements of the array");
}
/* ******************************************* */
@@ -2399,30 +2634,30 @@ void ANIM_OT_keyframe_clear_button(wmOperatorType *ot)
bool autokeyframe_cfra_can_key(Scene *scene, ID *id)
{
- float cfra = (float)CFRA; // XXX for now, this will do
-
- /* only filter if auto-key mode requires this */
- if (IS_AUTOKEY_ON(scene) == 0)
- return false;
-
- if (IS_AUTOKEY_MODE(scene, EDITKEYS)) {
- /* Replace Mode:
- * For whole block, only key if there's a keyframe on that frame already
- * This is a valid assumption when we're blocking + tweaking
- */
- return id_frame_has_keyframe(id, cfra, ANIMFILTER_KEYS_LOCAL);
- }
- else {
- /* Normal Mode (or treat as being normal mode):
- *
- * Just in case the flags aren't set properly (i.e. only on/off is set, without a mode)
- * let's set the "normal" flag too, so that it will all be sane everywhere...
- */
- scene->toolsettings->autokey_mode = AUTOKEY_MODE_NORMAL;
-
- /* Can insert anytime we like... */
- return true;
- }
+ float cfra = (float)CFRA; // XXX for now, this will do
+
+ /* only filter if auto-key mode requires this */
+ if (IS_AUTOKEY_ON(scene) == 0)
+ return false;
+
+ if (IS_AUTOKEY_MODE(scene, EDITKEYS)) {
+ /* Replace Mode:
+ * For whole block, only key if there's a keyframe on that frame already
+ * This is a valid assumption when we're blocking + tweaking
+ */
+ return id_frame_has_keyframe(id, cfra, ANIMFILTER_KEYS_LOCAL);
+ }
+ else {
+ /* Normal Mode (or treat as being normal mode):
+ *
+ * Just in case the flags aren't set properly (i.e. only on/off is set, without a mode)
+ * let's set the "normal" flag too, so that it will all be sane everywhere...
+ */
+ scene->toolsettings->autokey_mode = AUTOKEY_MODE_NORMAL;
+
+ /* Can insert anytime we like... */
+ return true;
+ }
}
/* ******************************************* */
@@ -2433,48 +2668,49 @@ bool autokeyframe_cfra_can_key(Scene *scene, ID *id)
/* Checks if some F-Curve has a keyframe for a given frame */
bool fcurve_frame_has_keyframe(FCurve *fcu, float frame, short filter)
{
- /* quick sanity check */
- if (ELEM(NULL, fcu, fcu->bezt))
- return false;
-
- /* we either include all regardless of muting, or only non-muted */
- if ((filter & ANIMFILTER_KEYS_MUTED) || (fcu->flag & FCURVE_MUTED) == 0) {
- bool replace;
- int i = binarysearch_bezt_index(fcu->bezt, frame, fcu->totvert, &replace);
-
- /* binarysearch_bezt_index will set replace to be 0 or 1
- * - obviously, 1 represents a match
- */
- if (replace) {
- /* sanity check: 'i' may in rare cases exceed arraylen */
- if ((i >= 0) && (i < fcu->totvert))
- return true;
- }
- }
-
- return false;
+ /* quick sanity check */
+ if (ELEM(NULL, fcu, fcu->bezt))
+ return false;
+
+ /* we either include all regardless of muting, or only non-muted */
+ if ((filter & ANIMFILTER_KEYS_MUTED) || (fcu->flag & FCURVE_MUTED) == 0) {
+ bool replace;
+ int i = binarysearch_bezt_index(fcu->bezt, frame, fcu->totvert, &replace);
+
+ /* binarysearch_bezt_index will set replace to be 0 or 1
+ * - obviously, 1 represents a match
+ */
+ if (replace) {
+ /* sanity check: 'i' may in rare cases exceed arraylen */
+ if ((i >= 0) && (i < fcu->totvert))
+ return true;
+ }
+ }
+
+ return false;
}
/* Returns whether the current value of a given property differs from the interpolated value. */
bool fcurve_is_changed(PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float frame)
{
- PathResolvedRNA anim_rna;
- anim_rna.ptr = ptr;
- anim_rna.prop = prop;
- anim_rna.prop_index = fcu->array_index;
+ PathResolvedRNA anim_rna;
+ anim_rna.ptr = ptr;
+ anim_rna.prop = prop;
+ anim_rna.prop_index = fcu->array_index;
- float buffer[RNA_MAX_ARRAY_LENGTH];
- int count, index = fcu->array_index;
- float *values = setting_get_rna_values(NULL, &ptr, prop, false, buffer, RNA_MAX_ARRAY_LENGTH, &count);
+ float buffer[RNA_MAX_ARRAY_LENGTH];
+ int count, index = fcu->array_index;
+ float *values = setting_get_rna_values(
+ NULL, &ptr, prop, false, buffer, RNA_MAX_ARRAY_LENGTH, &count);
- float fcurve_val = calculate_fcurve(&anim_rna, fcu, frame);
- float cur_val = (index >= 0 && index < count) ? values[index] : 0.0f;
+ float fcurve_val = calculate_fcurve(&anim_rna, fcu, frame);
+ float cur_val = (index >= 0 && index < count) ? values[index] : 0.0f;
- if (values != buffer) {
- MEM_freeN(values);
- }
+ if (values != buffer) {
+ MEM_freeN(values);
+ }
- return !compare_ff_relative(fcurve_val, cur_val, FLT_EPSILON, 64);
+ return !compare_ff_relative(fcurve_val, cur_val, FLT_EPSILON, 64);
}
/* Checks whether an Action has a keyframe for a given frame
@@ -2482,91 +2718,91 @@ bool fcurve_is_changed(PointerRNA ptr, PropertyRNA *prop, FCurve *fcu, float fra
*/
static bool action_frame_has_keyframe(bAction *act, float frame, short filter)
{
- FCurve *fcu;
-
- /* can only find if there is data */
- if (act == NULL)
- return false;
-
- /* if only check non-muted, check if muted */
- if ((filter & ANIMFILTER_KEYS_MUTED) || (act->flag & ACT_MUTED))
- return false;
-
- /* loop over F-Curves, using binary-search to try to find matches
- * - this assumes that keyframes are only beztriples
- */
- for (fcu = act->curves.first; fcu; fcu = fcu->next) {
- /* only check if there are keyframes (currently only of type BezTriple) */
- if (fcu->bezt && fcu->totvert) {
- if (fcurve_frame_has_keyframe(fcu, frame, filter))
- return true;
- }
- }
-
- /* nothing found */
- return false;
+ FCurve *fcu;
+
+ /* can only find if there is data */
+ if (act == NULL)
+ return false;
+
+ /* if only check non-muted, check if muted */
+ if ((filter & ANIMFILTER_KEYS_MUTED) || (act->flag & ACT_MUTED))
+ return false;
+
+ /* loop over F-Curves, using binary-search to try to find matches
+ * - this assumes that keyframes are only beztriples
+ */
+ for (fcu = act->curves.first; fcu; fcu = fcu->next) {
+ /* only check if there are keyframes (currently only of type BezTriple) */
+ if (fcu->bezt && fcu->totvert) {
+ if (fcurve_frame_has_keyframe(fcu, frame, filter))
+ return true;
+ }
+ }
+
+ /* nothing found */
+ return false;
}
/* Checks whether an Object has a keyframe for a given frame */
static bool object_frame_has_keyframe(Object *ob, float frame, short filter)
{
- /* error checking */
- if (ob == NULL)
- return false;
-
- /* check own animation data - specifically, the action it contains */
- if ((ob->adt) && (ob->adt->action)) {
- /* T41525 - When the active action is a NLA strip being edited,
- * we need to correct the frame number to "look inside" the
- * remapped action
- */
- float ob_frame = BKE_nla_tweakedit_remap(ob->adt, frame, NLATIME_CONVERT_UNMAP);
-
- if (action_frame_has_keyframe(ob->adt->action, ob_frame, filter))
- return true;
- }
-
- /* try shapekey keyframes (if available, and allowed by filter) */
- if (!(filter & ANIMFILTER_KEYS_LOCAL) && !(filter & ANIMFILTER_KEYS_NOSKEY)) {
- Key *key = BKE_key_from_object(ob);
-
- /* shapekeys can have keyframes ('Relative Shape Keys')
- * or depend on time (old 'Absolute Shape Keys')
- */
-
- /* 1. test for relative (with keyframes) */
- if (id_frame_has_keyframe((ID *)key, frame, filter))
- return true;
-
- /* 2. test for time */
- /* TODO... yet to be implemented (this feature may evolve before then anyway) */
- }
-
- /* try materials */
- if (!(filter & ANIMFILTER_KEYS_LOCAL) && !(filter & ANIMFILTER_KEYS_NOMAT)) {
- /* if only active, then we can skip a lot of looping */
- if (filter & ANIMFILTER_KEYS_ACTIVE) {
- Material *ma = give_current_material(ob, (ob->actcol + 1));
-
- /* we only retrieve the active material... */
- if (id_frame_has_keyframe((ID *)ma, frame, filter))
- return true;
- }
- else {
- int a;
-
- /* loop over materials */
- for (a = 0; a < ob->totcol; a++) {
- Material *ma = give_current_material(ob, a + 1);
-
- if (id_frame_has_keyframe((ID *)ma, frame, filter))
- return true;
- }
- }
- }
-
- /* nothing found */
- return false;
+ /* error checking */
+ if (ob == NULL)
+ return false;
+
+ /* check own animation data - specifically, the action it contains */
+ if ((ob->adt) && (ob->adt->action)) {
+ /* T41525 - When the active action is a NLA strip being edited,
+ * we need to correct the frame number to "look inside" the
+ * remapped action
+ */
+ float ob_frame = BKE_nla_tweakedit_remap(ob->adt, frame, NLATIME_CONVERT_UNMAP);
+
+ if (action_frame_has_keyframe(ob->adt->action, ob_frame, filter))
+ return true;
+ }
+
+ /* try shapekey keyframes (if available, and allowed by filter) */
+ if (!(filter & ANIMFILTER_KEYS_LOCAL) && !(filter & ANIMFILTER_KEYS_NOSKEY)) {
+ Key *key = BKE_key_from_object(ob);
+
+ /* shapekeys can have keyframes ('Relative Shape Keys')
+ * or depend on time (old 'Absolute Shape Keys')
+ */
+
+ /* 1. test for relative (with keyframes) */
+ if (id_frame_has_keyframe((ID *)key, frame, filter))
+ return true;
+
+ /* 2. test for time */
+ /* TODO... yet to be implemented (this feature may evolve before then anyway) */
+ }
+
+ /* try materials */
+ if (!(filter & ANIMFILTER_KEYS_LOCAL) && !(filter & ANIMFILTER_KEYS_NOMAT)) {
+ /* if only active, then we can skip a lot of looping */
+ if (filter & ANIMFILTER_KEYS_ACTIVE) {
+ Material *ma = give_current_material(ob, (ob->actcol + 1));
+
+ /* we only retrieve the active material... */
+ if (id_frame_has_keyframe((ID *)ma, frame, filter))
+ return true;
+ }
+ else {
+ int a;
+
+ /* loop over materials */
+ for (a = 0; a < ob->totcol; a++) {
+ Material *ma = give_current_material(ob, a + 1);
+
+ if (id_frame_has_keyframe((ID *)ma, frame, filter))
+ return true;
+ }
+ }
+ }
+
+ /* nothing found */
+ return false;
}
/* --------------- API ------------------- */
@@ -2574,88 +2810,88 @@ static bool object_frame_has_keyframe(Object *ob, float frame, short filter)
/* Checks whether a keyframe exists for the given ID-block one the given frame */
bool id_frame_has_keyframe(ID *id, float frame, short filter)
{
- /* sanity checks */
- if (id == NULL)
- return false;
-
- /* perform special checks for 'macro' types */
- switch (GS(id->name)) {
- case ID_OB: /* object */
- return object_frame_has_keyframe((Object *)id, frame, filter);
+ /* sanity checks */
+ if (id == NULL)
+ return false;
+
+ /* perform special checks for 'macro' types */
+ switch (GS(id->name)) {
+ case ID_OB: /* object */
+ return object_frame_has_keyframe((Object *)id, frame, filter);
#if 0
- // XXX TODO... for now, just use 'normal' behavior
- case ID_SCE: /* scene */
- break;
+ // XXX TODO... for now, just use 'normal' behavior
+ case ID_SCE: /* scene */
+ break;
#endif
- default: /* 'normal type' */
- {
- AnimData *adt = BKE_animdata_from_id(id);
-
- /* only check keyframes in active action */
- if (adt)
- return action_frame_has_keyframe(adt->action, frame, filter);
- break;
- }
- }
-
-
- /* no keyframe found */
- return false;
+ default: /* 'normal type' */
+ {
+ AnimData *adt = BKE_animdata_from_id(id);
+
+ /* only check keyframes in active action */
+ if (adt)
+ return action_frame_has_keyframe(adt->action, frame, filter);
+ break;
+ }
+ }
+
+ /* no keyframe found */
+ return false;
}
/* ************************************************** */
bool ED_autokeyframe_object(bContext *C, Scene *scene, Object *ob, KeyingSet *ks)
{
- /* auto keyframing */
- if (autokeyframe_cfra_can_key(scene, &ob->id)) {
- ListBase dsources = {NULL, NULL};
-
- /* now insert the keyframe(s) using the Keying Set
- * 1) add datasource override for the Object
- * 2) insert keyframes
- * 3) free the extra info
- */
- ANIM_relative_keyingset_add_source(&dsources, &ob->id, NULL, NULL);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
- BLI_freelistN(&dsources);
-
- return true;
- }
- else {
- return false;
- }
+ /* auto keyframing */
+ if (autokeyframe_cfra_can_key(scene, &ob->id)) {
+ ListBase dsources = {NULL, NULL};
+
+ /* now insert the keyframe(s) using the Keying Set
+ * 1) add datasource override for the Object
+ * 2) insert keyframes
+ * 3) free the extra info
+ */
+ ANIM_relative_keyingset_add_source(&dsources, &ob->id, NULL, NULL);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ BLI_freelistN(&dsources);
+
+ return true;
+ }
+ else {
+ return false;
+ }
}
-bool ED_autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *pchan, KeyingSet *ks)
+bool ED_autokeyframe_pchan(
+ bContext *C, Scene *scene, Object *ob, bPoseChannel *pchan, KeyingSet *ks)
{
- if (autokeyframe_cfra_can_key(scene, &ob->id)) {
- ListBase dsources = {NULL, NULL};
-
- /* now insert the keyframe(s) using the Keying Set
- * 1) add datasource override for the PoseChannel
- * 2) insert keyframes
- * 3) free the extra info
- */
- ANIM_relative_keyingset_add_source(&dsources, &ob->id, &RNA_PoseBone, pchan);
- ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
- BLI_freelistN(&dsources);
-
- /* clear any unkeyed tags */
- if (pchan->bone) {
- pchan->bone->flag &= ~BONE_UNKEYED;
- }
-
- return true;
- }
- else {
- /* add unkeyed tags */
- if (pchan->bone) {
- pchan->bone->flag |= BONE_UNKEYED;
- }
-
- return false;
- }
+ if (autokeyframe_cfra_can_key(scene, &ob->id)) {
+ ListBase dsources = {NULL, NULL};
+
+ /* now insert the keyframe(s) using the Keying Set
+ * 1) add datasource override for the PoseChannel
+ * 2) insert keyframes
+ * 3) free the extra info
+ */
+ ANIM_relative_keyingset_add_source(&dsources, &ob->id, &RNA_PoseBone, pchan);
+ ANIM_apply_keyingset(C, &dsources, NULL, ks, MODIFYKEY_MODE_INSERT, (float)CFRA);
+ BLI_freelistN(&dsources);
+
+ /* clear any unkeyed tags */
+ if (pchan->bone) {
+ pchan->bone->flag &= ~BONE_UNKEYED;
+ }
+
+ return true;
+ }
+ else {
+ /* add unkeyed tags */
+ if (pchan->bone) {
+ pchan->bone->flag |= BONE_UNKEYED;
+ }
+
+ return false;
+ }
}
/* -------------------------------------------------------------------- */
@@ -2665,28 +2901,28 @@ bool ED_autokeyframe_pchan(bContext *C, Scene *scene, Object *ob, bPoseChannel *
/** Use for insert/delete key-frame. */
static KeyingSet *keyingset_get_from_op_with_error(wmOperator *op, PropertyRNA *prop, Scene *scene)
{
- KeyingSet *ks = NULL;
- const int prop_type = RNA_property_type(prop);
- if (prop_type == PROP_ENUM) {
- int type = RNA_property_enum_get(op->ptr, prop);
- ks = ANIM_keyingset_get_from_enum_type(scene, type);
- if (ks == NULL) {
- BKE_report(op->reports, RPT_ERROR, "No active keying set");
- }
- }
- else if (prop_type == PROP_STRING) {
- char type_id[MAX_ID_NAME - 2];
- RNA_property_string_get(op->ptr, prop, type_id);
- ks = ANIM_keyingset_get_from_idname(scene, type_id);
-
- if (ks == NULL) {
- BKE_reportf(op->reports, RPT_ERROR, "Keying set '%s' not found", type_id);
- }
- }
- else {
- BLI_assert(0);
- }
- return ks;
+ KeyingSet *ks = NULL;
+ const int prop_type = RNA_property_type(prop);
+ if (prop_type == PROP_ENUM) {
+ int type = RNA_property_enum_get(op->ptr, prop);
+ ks = ANIM_keyingset_get_from_enum_type(scene, type);
+ if (ks == NULL) {
+ BKE_report(op->reports, RPT_ERROR, "No active keying set");
+ }
+ }
+ else if (prop_type == PROP_STRING) {
+ char type_id[MAX_ID_NAME - 2];
+ RNA_property_string_get(op->ptr, prop, type_id);
+ ks = ANIM_keyingset_get_from_idname(scene, type_id);
+
+ if (ks == NULL) {
+ BKE_reportf(op->reports, RPT_ERROR, "Keying set '%s' not found", type_id);
+ }
+ }
+ else {
+ BLI_assert(0);
+ }
+ return ks;
}
/** \} */
diff --git a/source/blender/editors/animation/keyingsets.c b/source/blender/editors/animation/keyingsets.c
index 654543c9d5d..93bae636571 100644
--- a/source/blender/editors/animation/keyingsets.c
+++ b/source/blender/editors/animation/keyingsets.c
@@ -21,7 +21,6 @@
* \ingroup edanimation
*/
-
#include <stdio.h>
#include <stddef.h>
#include <string.h>
@@ -68,209 +67,208 @@
/* poll callback for adding default KeyingSet */
static bool keyingset_poll_default_add(bContext *C)
{
- /* as long as there's an active Scene, it's fine */
- return (CTX_data_scene(C) != NULL);
+ /* as long as there's an active Scene, it's fine */
+ return (CTX_data_scene(C) != NULL);
}
/* poll callback for editing active KeyingSet */
static bool keyingset_poll_active_edit(bContext *C)
{
- Scene *scene = CTX_data_scene(C);
+ Scene *scene = CTX_data_scene(C);
- if (scene == NULL)
- return 0;
+ if (scene == NULL)
+ return 0;
- /* there must be an active KeyingSet (and KeyingSets) */
- return ((scene->active_keyingset > 0) && (scene->keyingsets.first));
+ /* there must be an active KeyingSet (and KeyingSets) */
+ return ((scene->active_keyingset > 0) && (scene->keyingsets.first));
}
/* poll callback for editing active KeyingSet Path */
static bool keyingset_poll_activePath_edit(bContext *C)
{
- Scene *scene = CTX_data_scene(C);
- KeyingSet *ks;
-
- if (scene == NULL)
- return 0;
- if (scene->active_keyingset <= 0)
- return 0;
- else
- ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
-
- /* there must be an active KeyingSet and an active path */
- return ((ks) && (ks->paths.first) && (ks->active_path > 0));
+ Scene *scene = CTX_data_scene(C);
+ KeyingSet *ks;
+
+ if (scene == NULL)
+ return 0;
+ if (scene->active_keyingset <= 0)
+ return 0;
+ else
+ ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
+
+ /* there must be an active KeyingSet and an active path */
+ return ((ks) && (ks->paths.first) && (ks->active_path > 0));
}
-
/* Add a Default (Empty) Keying Set ------------------------- */
static int add_default_keyingset_exec(bContext *C, wmOperator *UNUSED(op))
{
- Scene *scene = CTX_data_scene(C);
- short flag = 0, keyingflag = 0;
+ Scene *scene = CTX_data_scene(C);
+ short flag = 0, keyingflag = 0;
- /* validate flags
- * - absolute KeyingSets should be created by default
- */
- flag |= KEYINGSET_ABSOLUTE;
+ /* validate flags
+ * - absolute KeyingSets should be created by default
+ */
+ flag |= KEYINGSET_ABSOLUTE;
- /* 2nd arg is 0 to indicate that we don't want to include autokeying mode related settings */
- keyingflag = ANIM_get_keyframing_flags(scene, 0);
+ /* 2nd arg is 0 to indicate that we don't want to include autokeying mode related settings */
+ keyingflag = ANIM_get_keyframing_flags(scene, 0);
- /* call the API func, and set the active keyingset index */
- BKE_keyingset_add(&scene->keyingsets, NULL, NULL, flag, keyingflag);
+ /* call the API func, and set the active keyingset index */
+ BKE_keyingset_add(&scene->keyingsets, NULL, NULL, flag, keyingflag);
- scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
+ scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
- /* send notifiers */
- WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
+ /* send notifiers */
+ WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ANIM_OT_keying_set_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Empty Keying Set";
- ot->idname = "ANIM_OT_keying_set_add";
- ot->description = "Add a new (empty) Keying Set to the active Scene";
-
- /* callbacks */
- ot->exec = add_default_keyingset_exec;
- ot->poll = keyingset_poll_default_add;
+ /* identifiers */
+ ot->name = "Add Empty Keying Set";
+ ot->idname = "ANIM_OT_keying_set_add";
+ ot->description = "Add a new (empty) Keying Set to the active Scene";
+
+ /* callbacks */
+ ot->exec = add_default_keyingset_exec;
+ ot->poll = keyingset_poll_default_add;
}
/* Remove 'Active' Keying Set ------------------------- */
static int remove_active_keyingset_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- KeyingSet *ks;
-
- /* verify the Keying Set to use:
- * - use the active one
- * - return error if it doesn't exist
- */
- if (scene->active_keyingset == 0) {
- BKE_report(op->reports, RPT_ERROR, "No active keying set to remove");
- return OPERATOR_CANCELLED;
- }
- else if (scene->active_keyingset < 0) {
- BKE_report(op->reports, RPT_ERROR, "Cannot remove built in keying set");
- return OPERATOR_CANCELLED;
- }
- else
- ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
-
- /* free KeyingSet's data, then remove it from the scene */
- BKE_keyingset_free(ks);
- BLI_freelinkN(&scene->keyingsets, ks);
-
- /* the active one should now be the previously second-to-last one */
- scene->active_keyingset--;
-
- /* send notifiers */
- WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
-
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ KeyingSet *ks;
+
+ /* verify the Keying Set to use:
+ * - use the active one
+ * - return error if it doesn't exist
+ */
+ if (scene->active_keyingset == 0) {
+ BKE_report(op->reports, RPT_ERROR, "No active keying set to remove");
+ return OPERATOR_CANCELLED;
+ }
+ else if (scene->active_keyingset < 0) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot remove built in keying set");
+ return OPERATOR_CANCELLED;
+ }
+ else
+ ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
+
+ /* free KeyingSet's data, then remove it from the scene */
+ BKE_keyingset_free(ks);
+ BLI_freelinkN(&scene->keyingsets, ks);
+
+ /* the active one should now be the previously second-to-last one */
+ scene->active_keyingset--;
+
+ /* send notifiers */
+ WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
+
+ return OPERATOR_FINISHED;
}
void ANIM_OT_keying_set_remove(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Active Keying Set";
- ot->idname = "ANIM_OT_keying_set_remove";
- ot->description = "Remove the active Keying Set";
-
- /* callbacks */
- ot->exec = remove_active_keyingset_exec;
- ot->poll = keyingset_poll_active_edit;
+ /* identifiers */
+ ot->name = "Remove Active Keying Set";
+ ot->idname = "ANIM_OT_keying_set_remove";
+ ot->description = "Remove the active Keying Set";
+
+ /* callbacks */
+ ot->exec = remove_active_keyingset_exec;
+ ot->poll = keyingset_poll_active_edit;
}
/* Add Empty Keying Set Path ------------------------- */
static int add_empty_ks_path_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- KeyingSet *ks;
- KS_Path *ksp;
-
- /* verify the Keying Set to use:
- * - use the active one
- * - return error if it doesn't exist
- */
- if (scene->active_keyingset == 0) {
- BKE_report(op->reports, RPT_ERROR, "No active keying set to add empty path to");
- return OPERATOR_CANCELLED;
- }
- else
- ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
-
- /* don't use the API method for this, since that checks on values... */
- ksp = MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty");
- BLI_addtail(&ks->paths, ksp);
- ks->active_path = BLI_listbase_count(&ks->paths);
-
- ksp->groupmode = KSP_GROUP_KSNAME; // XXX?
- ksp->idtype = ID_OB;
- ksp->flag = KSP_FLAG_WHOLE_ARRAY;
-
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ KeyingSet *ks;
+ KS_Path *ksp;
+
+ /* verify the Keying Set to use:
+ * - use the active one
+ * - return error if it doesn't exist
+ */
+ if (scene->active_keyingset == 0) {
+ BKE_report(op->reports, RPT_ERROR, "No active keying set to add empty path to");
+ return OPERATOR_CANCELLED;
+ }
+ else
+ ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
+
+ /* don't use the API method for this, since that checks on values... */
+ ksp = MEM_callocN(sizeof(KS_Path), "KeyingSetPath Empty");
+ BLI_addtail(&ks->paths, ksp);
+ ks->active_path = BLI_listbase_count(&ks->paths);
+
+ ksp->groupmode = KSP_GROUP_KSNAME; // XXX?
+ ksp->idtype = ID_OB;
+ ksp->flag = KSP_FLAG_WHOLE_ARRAY;
+
+ return OPERATOR_FINISHED;
}
void ANIM_OT_keying_set_path_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add Empty Keying Set Path";
- ot->idname = "ANIM_OT_keying_set_path_add";
- ot->description = "Add empty path to active Keying Set";
-
- /* callbacks */
- ot->exec = add_empty_ks_path_exec;
- ot->poll = keyingset_poll_active_edit;
+ /* identifiers */
+ ot->name = "Add Empty Keying Set Path";
+ ot->idname = "ANIM_OT_keying_set_path_add";
+ ot->description = "Add empty path to active Keying Set";
+
+ /* callbacks */
+ ot->exec = add_empty_ks_path_exec;
+ ot->poll = keyingset_poll_active_edit;
}
/* Remove Active Keying Set Path ------------------------- */
static int remove_active_ks_path_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- KeyingSet *ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
-
- /* if there is a KeyingSet, find the nominated path to remove */
- if (ks) {
- KS_Path *ksp = BLI_findlink(&ks->paths, ks->active_path - 1);
-
- if (ksp) {
- /* remove the active path from the KeyingSet */
- BKE_keyingset_free_path(ks, ksp);
-
- /* the active path should now be the previously second-to-last active one */
- ks->active_path--;
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "No active keying set path to remove");
- return OPERATOR_CANCELLED;
- }
- }
- else {
- BKE_report(op->reports, RPT_ERROR, "No active keying set to remove a path from");
- return OPERATOR_CANCELLED;
- }
-
- return OPERATOR_FINISHED;
+ Scene *scene = CTX_data_scene(C);
+ KeyingSet *ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
+
+ /* if there is a KeyingSet, find the nominated path to remove */
+ if (ks) {
+ KS_Path *ksp = BLI_findlink(&ks->paths, ks->active_path - 1);
+
+ if (ksp) {
+ /* remove the active path from the KeyingSet */
+ BKE_keyingset_free_path(ks, ksp);
+
+ /* the active path should now be the previously second-to-last active one */
+ ks->active_path--;
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "No active keying set path to remove");
+ return OPERATOR_CANCELLED;
+ }
+ }
+ else {
+ BKE_report(op->reports, RPT_ERROR, "No active keying set to remove a path from");
+ return OPERATOR_CANCELLED;
+ }
+
+ return OPERATOR_FINISHED;
}
void ANIM_OT_keying_set_path_remove(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove Active Keying Set Path";
- ot->idname = "ANIM_OT_keying_set_path_remove";
- ot->description = "Remove active Path from active Keying Set";
-
- /* callbacks */
- ot->exec = remove_active_ks_path_exec;
- ot->poll = keyingset_poll_activePath_edit;
+ /* identifiers */
+ ot->name = "Remove Active Keying Set Path";
+ ot->idname = "ANIM_OT_keying_set_path_remove";
+ ot->description = "Remove active Path from active Keying Set";
+
+ /* callbacks */
+ ot->exec = remove_active_ks_path_exec;
+ ot->poll = keyingset_poll_activePath_edit;
}
/* ************************************************** */
@@ -280,184 +278,184 @@ void ANIM_OT_keying_set_path_remove(wmOperatorType *ot)
static int add_keyingset_button_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- KeyingSet *ks = NULL;
- PropertyRNA *prop = NULL;
- PointerRNA ptr = {{NULL}};
- char *path = NULL;
- short success = 0;
- int index = 0, pflag = 0;
- const bool all = RNA_boolean_get(op->ptr, "all");
-
- /* try to add to keyingset using property retrieved from UI */
- if (!UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
- /* pass event on if no active button found */
- return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
- }
-
- /* verify the Keying Set to use:
- * - use the active one for now (more control over this can be added later)
- * - add a new one if it doesn't exist
- */
- if (scene->active_keyingset == 0) {
- short flag = 0, keyingflag = 0;
-
- /* validate flags
- * - absolute KeyingSets should be created by default
- */
- flag |= KEYINGSET_ABSOLUTE;
-
- keyingflag |= ANIM_get_keyframing_flags(scene, 0);
-
- if (IS_AUTOKEY_FLAG(scene, XYZ2RGB))
- keyingflag |= INSERTKEY_XYZ2RGB;
-
- /* call the API func, and set the active keyingset index */
- ks = BKE_keyingset_add(&scene->keyingsets, "ButtonKeyingSet", "Button Keying Set", flag, keyingflag);
-
- scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
- }
- else if (scene->active_keyingset < 0) {
- BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in keying set");
- return OPERATOR_CANCELLED;
- }
- else {
- ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
- }
-
- /* check if property is able to be added */
- if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
- path = RNA_path_from_ID_to_property(&ptr, prop);
-
- if (path) {
- /* set flags */
- if (all) {
- pflag |= KSP_FLAG_WHOLE_ARRAY;
-
- /* we need to set the index for this to 0, even though it may break in some cases, this is
- * necessary if we want the entire array for most cases to get included without the user
- * having to worry about where they clicked
- */
- index = 0;
- }
-
- /* add path to this setting */
- BKE_keyingset_add_path(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
- ks->active_path = BLI_listbase_count(&ks->paths);
- success = 1;
-
- /* free the temp path created */
- MEM_freeN(path);
- }
- }
-
- if (success) {
- /* send updates */
- WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
-
- /* show notification/report header, so that users notice that something changed */
- BKE_reportf(op->reports, RPT_INFO, "Property added to Keying Set: '%s'", ks->name);
- }
-
- return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ Scene *scene = CTX_data_scene(C);
+ KeyingSet *ks = NULL;
+ PropertyRNA *prop = NULL;
+ PointerRNA ptr = {{NULL}};
+ char *path = NULL;
+ short success = 0;
+ int index = 0, pflag = 0;
+ const bool all = RNA_boolean_get(op->ptr, "all");
+
+ /* try to add to keyingset using property retrieved from UI */
+ if (!UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
+ /* pass event on if no active button found */
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ /* verify the Keying Set to use:
+ * - use the active one for now (more control over this can be added later)
+ * - add a new one if it doesn't exist
+ */
+ if (scene->active_keyingset == 0) {
+ short flag = 0, keyingflag = 0;
+
+ /* validate flags
+ * - absolute KeyingSets should be created by default
+ */
+ flag |= KEYINGSET_ABSOLUTE;
+
+ keyingflag |= ANIM_get_keyframing_flags(scene, 0);
+
+ if (IS_AUTOKEY_FLAG(scene, XYZ2RGB))
+ keyingflag |= INSERTKEY_XYZ2RGB;
+
+ /* call the API func, and set the active keyingset index */
+ ks = BKE_keyingset_add(
+ &scene->keyingsets, "ButtonKeyingSet", "Button Keying Set", flag, keyingflag);
+
+ scene->active_keyingset = BLI_listbase_count(&scene->keyingsets);
+ }
+ else if (scene->active_keyingset < 0) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in keying set");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
+ }
+
+ /* check if property is able to be added */
+ if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
+ path = RNA_path_from_ID_to_property(&ptr, prop);
+
+ if (path) {
+ /* set flags */
+ if (all) {
+ pflag |= KSP_FLAG_WHOLE_ARRAY;
+
+ /* we need to set the index for this to 0, even though it may break in some cases, this is
+ * necessary if we want the entire array for most cases to get included without the user
+ * having to worry about where they clicked
+ */
+ index = 0;
+ }
+
+ /* add path to this setting */
+ BKE_keyingset_add_path(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
+ ks->active_path = BLI_listbase_count(&ks->paths);
+ success = 1;
+
+ /* free the temp path created */
+ MEM_freeN(path);
+ }
+ }
+
+ if (success) {
+ /* send updates */
+ WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
+
+ /* show notification/report header, so that users notice that something changed */
+ BKE_reportf(op->reports, RPT_INFO, "Property added to Keying Set: '%s'", ks->name);
+ }
+
+ return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void ANIM_OT_keyingset_button_add(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Add to Keying Set";
- ot->idname = "ANIM_OT_keyingset_button_add";
- ot->description = "Add current UI-active property to current keying set";
+ /* identifiers */
+ ot->name = "Add to Keying Set";
+ ot->idname = "ANIM_OT_keyingset_button_add";
+ ot->description = "Add current UI-active property to current keying set";
- /* callbacks */
- ot->exec = add_keyingset_button_exec;
- //op->poll = ???
+ /* callbacks */
+ ot->exec = add_keyingset_button_exec;
+ //op->poll = ???
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
- /* properties */
- RNA_def_boolean(ot->srna, "all", 1, "All", "Add all elements of the array to a Keying Set");
+ /* properties */
+ RNA_def_boolean(ot->srna, "all", 1, "All", "Add all elements of the array to a Keying Set");
}
/* Remove from KeyingSet Button Operator ------------------------ */
static int remove_keyingset_button_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- KeyingSet *ks = NULL;
- PropertyRNA *prop = NULL;
- PointerRNA ptr = {{NULL}};
- char *path = NULL;
- short success = 0;
- int index = 0;
-
- /* try to add to keyingset using property retrieved from UI */
- if (UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
- /* pass event on if no active button found */
- return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
- }
-
- /* verify the Keying Set to use:
- * - use the active one for now (more control over this can be added later)
- * - return error if it doesn't exist
- */
- if (scene->active_keyingset == 0) {
- BKE_report(op->reports, RPT_ERROR, "No active keying set to remove property from");
- return OPERATOR_CANCELLED;
- }
- else if (scene->active_keyingset < 0) {
- BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in keying set");
- return OPERATOR_CANCELLED;
- }
- else {
- ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
- }
-
- if (ptr.id.data && ptr.data && prop) {
- path = RNA_path_from_ID_to_property(&ptr, prop);
-
- if (path) {
- KS_Path *ksp;
-
- /* try to find a path matching this description */
- ksp = BKE_keyingset_find_path(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME);
-
- if (ksp) {
- BKE_keyingset_free_path(ks, ksp);
- success = 1;
- }
-
- /* free temp path used */
- MEM_freeN(path);
- }
- }
-
-
- if (success) {
- /* send updates */
- WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
-
- /* show warning */
- BKE_report(op->reports, RPT_INFO, "Property removed from Keying Set");
- }
-
- return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ Scene *scene = CTX_data_scene(C);
+ KeyingSet *ks = NULL;
+ PropertyRNA *prop = NULL;
+ PointerRNA ptr = {{NULL}};
+ char *path = NULL;
+ short success = 0;
+ int index = 0;
+
+ /* try to add to keyingset using property retrieved from UI */
+ if (UI_context_active_but_prop_get(C, &ptr, &prop, &index)) {
+ /* pass event on if no active button found */
+ return (OPERATOR_CANCELLED | OPERATOR_PASS_THROUGH);
+ }
+
+ /* verify the Keying Set to use:
+ * - use the active one for now (more control over this can be added later)
+ * - return error if it doesn't exist
+ */
+ if (scene->active_keyingset == 0) {
+ BKE_report(op->reports, RPT_ERROR, "No active keying set to remove property from");
+ return OPERATOR_CANCELLED;
+ }
+ else if (scene->active_keyingset < 0) {
+ BKE_report(op->reports, RPT_ERROR, "Cannot remove property from built in keying set");
+ return OPERATOR_CANCELLED;
+ }
+ else {
+ ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
+ }
+
+ if (ptr.id.data && ptr.data && prop) {
+ path = RNA_path_from_ID_to_property(&ptr, prop);
+
+ if (path) {
+ KS_Path *ksp;
+
+ /* try to find a path matching this description */
+ ksp = BKE_keyingset_find_path(ks, ptr.id.data, ks->name, path, index, KSP_GROUP_KSNAME);
+
+ if (ksp) {
+ BKE_keyingset_free_path(ks, ksp);
+ success = 1;
+ }
+
+ /* free temp path used */
+ MEM_freeN(path);
+ }
+ }
+
+ if (success) {
+ /* send updates */
+ WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
+
+ /* show warning */
+ BKE_report(op->reports, RPT_INFO, "Property removed from Keying Set");
+ }
+
+ return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}
void ANIM_OT_keyingset_button_remove(wmOperatorType *ot)
{
- /* identifiers */
- ot->name = "Remove from Keying Set";
- ot->idname = "ANIM_OT_keyingset_button_remove";
- ot->description = "Remove current UI-active property from current keying set";
+ /* identifiers */
+ ot->name = "Remove from Keying Set";
+ ot->idname = "ANIM_OT_keyingset_button_remove";
+ ot->description = "Remove current UI-active property from current keying set";
- /* callbacks */
- ot->exec = remove_keyingset_button_exec;
- //op->poll = ???
+ /* callbacks */
+ ot->exec = remove_keyingset_button_exec;
+ //op->poll = ???
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************************************* */
@@ -467,53 +465,54 @@ void ANIM_OT_keyingset_button_remove(wmOperatorType *ot)
static int keyingset_active_menu_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
{
- uiPopupMenu *pup;
- uiLayout *layout;
+ uiPopupMenu *pup;
+ uiLayout *layout;
- /* call the menu, which will call this operator again, hence the canceled */
- pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
- layout = UI_popup_menu_layout(pup);
- uiItemsEnumO(layout, "ANIM_OT_keying_set_active_set", "type");
- UI_popup_menu_end(C, pup);
+ /* call the menu, which will call this operator again, hence the canceled */
+ pup = UI_popup_menu_begin(C, op->type->name, ICON_NONE);
+ layout = UI_popup_menu_layout(pup);
+ uiItemsEnumO(layout, "ANIM_OT_keying_set_active_set", "type");
+ UI_popup_menu_end(C, pup);
- return OPERATOR_INTERFACE;
+ return OPERATOR_INTERFACE;
}
static int keyingset_active_menu_exec(bContext *C, wmOperator *op)
{
- Scene *scene = CTX_data_scene(C);
- int type = RNA_enum_get(op->ptr, "type");
+ Scene *scene = CTX_data_scene(C);
+ int type = RNA_enum_get(op->ptr, "type");
- /* If type == 0, it will deselect any active keying set. */
- scene->active_keyingset = type;
+ /* If type == 0, it will deselect any active keying set. */
+ scene->active_keyingset = type;
- /* send notifiers */
- WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
+ /* send notifiers */
+ WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void ANIM_OT_keying_set_active_set(wmOperatorType *ot)
{
- PropertyRNA *prop;
-
- /* identifiers */
- ot->name = "Set Active Keying Set";
- ot->idname = "ANIM_OT_keying_set_active_set";
- ot->description = "Select a new keying set as the active one";
-
- /* callbacks */
- ot->invoke = keyingset_active_menu_invoke;
- ot->exec = keyingset_active_menu_exec;
- ot->poll = ED_operator_areaactive;
-
- /* flags */
- ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
-
- /* keyingset to use (dynamic enum) */
- prop = RNA_def_enum(ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
- RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
- // RNA_def_property_flag(prop, PROP_HIDDEN);
+ PropertyRNA *prop;
+
+ /* identifiers */
+ ot->name = "Set Active Keying Set";
+ ot->idname = "ANIM_OT_keying_set_active_set";
+ ot->description = "Select a new keying set as the active one";
+
+ /* callbacks */
+ ot->invoke = keyingset_active_menu_invoke;
+ ot->exec = keyingset_active_menu_exec;
+ ot->poll = ED_operator_areaactive;
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+ /* keyingset to use (dynamic enum) */
+ prop = RNA_def_enum(
+ ot->srna, "type", DummyRNA_DEFAULT_items, 0, "Keying Set", "The Keying Set to use");
+ RNA_def_enum_funcs(prop, ANIM_keying_sets_enum_itemf);
+ // RNA_def_property_flag(prop, PROP_HIDDEN);
}
/* ******************************************* */
@@ -530,42 +529,42 @@ ListBase builtin_keyingsets = {NULL, NULL};
/* Find KeyingSet type info given a name */
KeyingSetInfo *ANIM_keyingset_info_find_name(const char name[])
{
- /* sanity checks */
- if ((name == NULL) || (name[0] == 0))
- return NULL;
+ /* sanity checks */
+ if ((name == NULL) || (name[0] == 0))
+ return NULL;
- /* search by comparing names */
- return BLI_findstring(&keyingset_type_infos, name, offsetof(KeyingSetInfo, idname));
+ /* search by comparing names */
+ return BLI_findstring(&keyingset_type_infos, name, offsetof(KeyingSetInfo, idname));
}
/* Find builtin KeyingSet by name */
KeyingSet *ANIM_builtin_keyingset_get_named(KeyingSet *prevKS, const char name[])
{
- KeyingSet *ks, *first = NULL;
+ KeyingSet *ks, *first = NULL;
- /* sanity checks any name to check? */
- if (name[0] == 0)
- return NULL;
+ /* sanity checks any name to check? */
+ if (name[0] == 0)
+ return NULL;
- /* get first KeyingSet to use */
- if (prevKS && prevKS->next)
- first = prevKS->next;
- else
- first = builtin_keyingsets.first;
+ /* get first KeyingSet to use */
+ if (prevKS && prevKS->next)
+ first = prevKS->next;
+ else
+ first = builtin_keyingsets.first;
- /* loop over KeyingSets checking names */
- for (ks = first; ks; ks = ks->next) {
- if (STREQ(name, ks->idname))
- return ks;
- }
+ /* loop over KeyingSets checking names */
+ for (ks = first; ks; ks = ks->next) {
+ if (STREQ(name, ks->idname))
+ return ks;
+ }
- /* complain about missing keying sets on debug builds */
+ /* complain about missing keying sets on debug builds */
#ifndef NDEBUG
- printf("%s: '%s' not found\n", __func__, name);
+ printf("%s: '%s' not found\n", __func__, name);
#endif
- /* no matches found */
- return NULL;
+ /* no matches found */
+ return NULL;
}
/* --------------- */
@@ -573,79 +572,79 @@ KeyingSet *ANIM_builtin_keyingset_get_named(KeyingSet *prevKS, const char name[]
/* Add the given KeyingSetInfo to the list of type infos, and create an appropriate builtin set too */
void ANIM_keyingset_info_register(KeyingSetInfo *ksi)
{
- KeyingSet *ks;
+ KeyingSet *ks;
- /* create a new KeyingSet
- * - inherit name and keyframing settings from the typeinfo
- */
- ks = BKE_keyingset_add(&builtin_keyingsets, ksi->idname, ksi->name, 1, ksi->keyingflag);
+ /* create a new KeyingSet
+ * - inherit name and keyframing settings from the typeinfo
+ */
+ ks = BKE_keyingset_add(&builtin_keyingsets, ksi->idname, ksi->name, 1, ksi->keyingflag);
- /* link this KeyingSet with its typeinfo */
- memcpy(&ks->typeinfo, ksi->idname, sizeof(ks->typeinfo));
+ /* link this KeyingSet with its typeinfo */
+ memcpy(&ks->typeinfo, ksi->idname, sizeof(ks->typeinfo));
- /* Copy description... */
- BLI_strncpy(ks->description, ksi->description, sizeof(ks->description));
+ /* Copy description... */
+ BLI_strncpy(ks->description, ksi->description, sizeof(ks->description));
- /* add type-info to the list */
- BLI_addtail(&keyingset_type_infos, ksi);
+ /* add type-info to the list */
+ BLI_addtail(&keyingset_type_infos, ksi);
}
/* Remove the given KeyingSetInfo from the list of type infos, and also remove the builtin set if appropriate */
void ANIM_keyingset_info_unregister(Main *bmain, KeyingSetInfo *ksi)
{
- KeyingSet *ks, *ksn;
+ KeyingSet *ks, *ksn;
- /* find relevant builtin KeyingSets which use this, and remove them */
- /* TODO: this isn't done now, since unregister is really only used atm when we
- * reload the scripts, which kindof defeats the purpose of "builtin"? */
- for (ks = builtin_keyingsets.first; ks; ks = ksn) {
- ksn = ks->next;
+ /* find relevant builtin KeyingSets which use this, and remove them */
+ /* TODO: this isn't done now, since unregister is really only used atm when we
+ * reload the scripts, which kindof defeats the purpose of "builtin"? */
+ for (ks = builtin_keyingsets.first; ks; ks = ksn) {
+ ksn = ks->next;
- /* remove if matching typeinfo name */
- if (STREQ(ks->typeinfo, ksi->idname)) {
- Scene *scene;
- BKE_keyingset_free(ks);
- BLI_remlink(&builtin_keyingsets, ks);
+ /* remove if matching typeinfo name */
+ if (STREQ(ks->typeinfo, ksi->idname)) {
+ Scene *scene;
+ BKE_keyingset_free(ks);
+ BLI_remlink(&builtin_keyingsets, ks);
- for (scene = bmain->scenes.first; scene; scene = scene->id.next)
- BLI_remlink_safe(&scene->keyingsets, ks);
+ for (scene = bmain->scenes.first; scene; scene = scene->id.next)
+ BLI_remlink_safe(&scene->keyingsets, ks);
- MEM_freeN(ks);
- }
- }
+ MEM_freeN(ks);
+ }
+ }
- /* free the type info */
- BLI_freelinkN(&keyingset_type_infos, ksi);
+ /* free the type info */
+ BLI_freelinkN(&keyingset_type_infos, ksi);
}
/* --------------- */
void ANIM_keyingset_infos_exit(void)
{
- KeyingSetInfo *ksi, *next;
+ KeyingSetInfo *ksi, *next;
- /* free type infos */
- for (ksi = keyingset_type_infos.first; ksi; ksi = next) {
- next = ksi->next;
+ /* free type infos */
+ for (ksi = keyingset_type_infos.first; ksi; ksi = next) {
+ next = ksi->next;
- /* free extra RNA data, and remove from list */
- if (ksi->ext.free)
- ksi->ext.free(ksi->ext.data);
- BLI_freelinkN(&keyingset_type_infos, ksi);
- }
+ /* free extra RNA data, and remove from list */
+ if (ksi->ext.free)
+ ksi->ext.free(ksi->ext.data);
+ BLI_freelinkN(&keyingset_type_infos, ksi);
+ }
- /* free builtin sets */
- BKE_keyingsets_free(&builtin_keyingsets);
+ /* free builtin sets */
+ BKE_keyingsets_free(&builtin_keyingsets);
}
/* Check if the ID appears in the paths specified by the KeyingSet */
bool ANIM_keyingset_find_id(KeyingSet *ks, ID *id)
{
- /* sanity checks */
- if (ELEM(NULL, ks, id))
- return false;
+ /* sanity checks */
+ if (ELEM(NULL, ks, id))
+ return false;
- return BLI_findptr(&ks->paths, id, offsetof(KS_Path, id)) != NULL;
+ return BLI_findptr(&ks->paths, id, offsetof(KS_Path, id)) != NULL;
}
/* ******************************************* */
@@ -656,132 +655,135 @@ bool ANIM_keyingset_find_id(KeyingSet *ks, ID *id)
/* Get the active Keying Set for the Scene provided */
KeyingSet *ANIM_scene_get_active_keyingset(Scene *scene)
{
- /* if no scene, we've got no hope of finding the Keying Set */
- if (scene == NULL)
- return NULL;
-
- /* currently, there are several possibilities here:
- * - 0: no active keying set
- * - > 0: one of the user-defined Keying Sets, but indices start from 0 (hence the -1)
- * - < 0: a builtin keying set
- */
- if (scene->active_keyingset > 0)
- return BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
- else
- return BLI_findlink(&builtin_keyingsets, (-scene->active_keyingset) - 1);
+ /* if no scene, we've got no hope of finding the Keying Set */
+ if (scene == NULL)
+ return NULL;
+
+ /* currently, there are several possibilities here:
+ * - 0: no active keying set
+ * - > 0: one of the user-defined Keying Sets, but indices start from 0 (hence the -1)
+ * - < 0: a builtin keying set
+ */
+ if (scene->active_keyingset > 0)
+ return BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
+ else
+ return BLI_findlink(&builtin_keyingsets, (-scene->active_keyingset) - 1);
}
/* Get the index of the Keying Set provided, for the given Scene */
int ANIM_scene_get_keyingset_index(Scene *scene, KeyingSet *ks)
{
- int index;
-
- /* if no KeyingSet provided, have none */
- if (ks == NULL)
- return 0;
-
- /* check if the KeyingSet exists in scene list */
- if (scene) {
- /* get index and if valid, return
- * - (absolute) Scene KeyingSets are from (>= 1)
- */
- index = BLI_findindex(&scene->keyingsets, ks);
- if (index != -1)
- return (index + 1);
- }
-
- /* still here, so try builtins list too
- * - builtins are from (<= -1)
- * - none/invalid is (= 0)
- */
- index = BLI_findindex(&builtin_keyingsets, ks);
- if (index != -1)
- return -(index + 1);
- else
- return 0;
+ int index;
+
+ /* if no KeyingSet provided, have none */
+ if (ks == NULL)
+ return 0;
+
+ /* check if the KeyingSet exists in scene list */
+ if (scene) {
+ /* get index and if valid, return
+ * - (absolute) Scene KeyingSets are from (>= 1)
+ */
+ index = BLI_findindex(&scene->keyingsets, ks);
+ if (index != -1)
+ return (index + 1);
+ }
+
+ /* still here, so try builtins list too
+ * - builtins are from (<= -1)
+ * - none/invalid is (= 0)
+ */
+ index = BLI_findindex(&builtin_keyingsets, ks);
+ if (index != -1)
+ return -(index + 1);
+ else
+ return 0;
}
/* Get Keying Set to use for Auto-Keyframing some transforms */
KeyingSet *ANIM_get_keyingset_for_autokeying(Scene *scene, const char *transformKSName)
{
- /* get KeyingSet to use
- * - use the active KeyingSet if defined (and user wants to use it for all autokeying),
- * or otherwise key transforms only
- */
- if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (scene->active_keyingset))
- return ANIM_scene_get_active_keyingset(scene);
- else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL))
- return ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_AVAILABLE_ID);
- else
- return ANIM_builtin_keyingset_get_named(NULL, transformKSName);
+ /* get KeyingSet to use
+ * - use the active KeyingSet if defined (and user wants to use it for all autokeying),
+ * or otherwise key transforms only
+ */
+ if (IS_AUTOKEY_FLAG(scene, ONLYKEYINGSET) && (scene->active_keyingset))
+ return ANIM_scene_get_active_keyingset(scene);
+ else if (IS_AUTOKEY_FLAG(scene, INSERTAVAIL))
+ return ANIM_builtin_keyingset_get_named(NULL, ANIM_KS_AVAILABLE_ID);
+ else
+ return ANIM_builtin_keyingset_get_named(NULL, transformKSName);
}
/* Menu of All Keying Sets ----------------------------- */
/* Dynamically populate an enum of Keying Sets */
-const EnumPropertyItem *ANIM_keying_sets_enum_itemf(bContext *C, PointerRNA *UNUSED(ptr), PropertyRNA *UNUSED(prop), bool *r_free)
+const EnumPropertyItem *ANIM_keying_sets_enum_itemf(bContext *C,
+ PointerRNA *UNUSED(ptr),
+ PropertyRNA *UNUSED(prop),
+ bool *r_free)
{
- Scene *scene = CTX_data_scene(C);
- KeyingSet *ks;
- EnumPropertyItem *item = NULL, item_tmp = {0};
- int totitem = 0;
- int i = 0;
-
- if (C == NULL) {
- return DummyRNA_DEFAULT_items;
- }
-
- /* active Keying Set
- * - only include entry if it exists
- */
- if (scene->active_keyingset) {
- /* active Keying Set */
- item_tmp.identifier = "__ACTIVE__";
- item_tmp.name = "Active Keying Set";
- item_tmp.value = i;
- RNA_enum_item_add(&item, &totitem, &item_tmp);
-
- /* separator */
- RNA_enum_item_add_separator(&item, &totitem);
- }
-
- i++;
-
- /* user-defined Keying Sets
- * - these are listed in the order in which they were defined for the active scene
- */
- if (scene->keyingsets.first) {
- for (ks = scene->keyingsets.first; ks; ks = ks->next, i++) {
- if (ANIM_keyingset_context_ok_poll(C, ks)) {
- item_tmp.identifier = ks->idname;
- item_tmp.name = ks->name;
- item_tmp.description = ks->description;
- item_tmp.value = i;
- RNA_enum_item_add(&item, &totitem, &item_tmp);
- }
- }
-
- /* separator */
- RNA_enum_item_add_separator(&item, &totitem);
- }
-
- /* builtin Keying Sets */
- i = -1;
- for (ks = builtin_keyingsets.first; ks; ks = ks->next, i--) {
- /* only show KeyingSet if context is suitable */
- if (ANIM_keyingset_context_ok_poll(C, ks)) {
- item_tmp.identifier = ks->idname;
- item_tmp.name = ks->name;
- item_tmp.description = ks->description;
- item_tmp.value = i;
- RNA_enum_item_add(&item, &totitem, &item_tmp);
- }
- }
-
- RNA_enum_item_end(&item, &totitem);
- *r_free = true;
-
- return item;
+ Scene *scene = CTX_data_scene(C);
+ KeyingSet *ks;
+ EnumPropertyItem *item = NULL, item_tmp = {0};
+ int totitem = 0;
+ int i = 0;
+
+ if (C == NULL) {
+ return DummyRNA_DEFAULT_items;
+ }
+
+ /* active Keying Set
+ * - only include entry if it exists
+ */
+ if (scene->active_keyingset) {
+ /* active Keying Set */
+ item_tmp.identifier = "__ACTIVE__";
+ item_tmp.name = "Active Keying Set";
+ item_tmp.value = i;
+ RNA_enum_item_add(&item, &totitem, &item_tmp);
+
+ /* separator */
+ RNA_enum_item_add_separator(&item, &totitem);
+ }
+
+ i++;
+
+ /* user-defined Keying Sets
+ * - these are listed in the order in which they were defined for the active scene
+ */
+ if (scene->keyingsets.first) {
+ for (ks = scene->keyingsets.first; ks; ks = ks->next, i++) {
+ if (ANIM_keyingset_context_ok_poll(C, ks)) {
+ item_tmp.identifier = ks->idname;
+ item_tmp.name = ks->name;
+ item_tmp.description = ks->description;
+ item_tmp.value = i;
+ RNA_enum_item_add(&item, &totitem, &item_tmp);
+ }
+ }
+
+ /* separator */
+ RNA_enum_item_add_separator(&item, &totitem);
+ }
+
+ /* builtin Keying Sets */
+ i = -1;
+ for (ks = builtin_keyingsets.first; ks; ks = ks->next, i--) {
+ /* only show KeyingSet if context is suitable */
+ if (ANIM_keyingset_context_ok_poll(C, ks)) {
+ item_tmp.identifier = ks->idname;
+ item_tmp.name = ks->name;
+ item_tmp.description = ks->description;
+ item_tmp.value = i;
+ RNA_enum_item_add(&item, &totitem, &item_tmp);
+ }
+ }
+
+ RNA_enum_item_end(&item, &totitem);
+ *r_free = true;
+
+ return item;
}
/**
@@ -794,28 +796,28 @@ const EnumPropertyItem *ANIM_keying_sets_enum_itemf(bContext *C, PointerRNA *UNU
*/
KeyingSet *ANIM_keyingset_get_from_enum_type(Scene *scene, int type)
{
- KeyingSet *ks = NULL;
-
- if (type == 0) {
- type = scene->active_keyingset;
- }
-
- if (type > 0) {
- ks = BLI_findlink(&scene->keyingsets, type - 1);
- }
- else {
- ks = BLI_findlink(&builtin_keyingsets, -type - 1);
- }
- return ks;
+ KeyingSet *ks = NULL;
+
+ if (type == 0) {
+ type = scene->active_keyingset;
+ }
+
+ if (type > 0) {
+ ks = BLI_findlink(&scene->keyingsets, type - 1);
+ }
+ else {
+ ks = BLI_findlink(&builtin_keyingsets, -type - 1);
+ }
+ return ks;
}
KeyingSet *ANIM_keyingset_get_from_idname(Scene *scene, const char *idname)
{
- KeyingSet *ks = BLI_findstring(&scene->keyingsets, idname, offsetof(KeyingSet, idname));
- if (ks == NULL) {
- ks = BLI_findstring(&builtin_keyingsets, idname, offsetof(KeyingSet, idname));
- }
- return ks;
+ KeyingSet *ks = BLI_findstring(&scene->keyingsets, idname, offsetof(KeyingSet, idname));
+ if (ks == NULL) {
+ ks = BLI_findstring(&builtin_keyingsets, idname, offsetof(KeyingSet, idname));
+ }
+ return ks;
}
/* ******************************************* */
@@ -826,19 +828,19 @@ KeyingSet *ANIM_keyingset_get_from_idname(Scene *scene, const char *idname)
/* Check if KeyingSet can be used in the current context */
bool ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks)
{
- if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
- KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
+ if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
+ KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
- /* get the associated 'type info' for this KeyingSet */
- if (ksi == NULL)
- return 0;
- /* TODO: check for missing callbacks! */
+ /* get the associated 'type info' for this KeyingSet */
+ if (ksi == NULL)
+ return 0;
+ /* TODO: check for missing callbacks! */
- /* check if it can be used in the current context */
- return (ksi->poll(ksi, C));
- }
+ /* check if it can be used in the current context */
+ return (ksi->poll(ksi, C));
+ }
- return true;
+ return true;
}
/* Special 'Overrides' Iterator for Relative KeyingSets ------ */
@@ -848,48 +850,50 @@ bool ANIM_keyingset_context_ok_poll(bContext *C, KeyingSet *ks)
* - do not allow this to be accessed from outside for now
*/
typedef struct tRKS_DSource {
- struct tRKS_DSource *next, *prev;
- PointerRNA ptr; /* the whole point of this exercise! */
+ struct tRKS_DSource *next, *prev;
+ PointerRNA ptr; /* the whole point of this exercise! */
} tRKS_DSource;
-
/* Iterator used for overriding the behavior of iterators defined for
* relative Keying Sets, with the main usage of this being operators
* requiring Auto Keyframing. Internal Use Only!
*/
-static void RKS_ITER_overrides_list(KeyingSetInfo *ksi, bContext *C, KeyingSet *ks, ListBase *dsources)
+static void RKS_ITER_overrides_list(KeyingSetInfo *ksi,
+ bContext *C,
+ KeyingSet *ks,
+ ListBase *dsources)
{
- tRKS_DSource *ds;
+ tRKS_DSource *ds;
- for (ds = dsources->first; ds; ds = ds->next) {
- /* run generate callback on this data */
- ksi->generate(ksi, C, ks, &ds->ptr);
- }
+ for (ds = dsources->first; ds; ds = ds->next) {
+ /* run generate callback on this data */
+ ksi->generate(ksi, C, ks, &ds->ptr);
+ }
}
/* Add new data source for relative Keying Sets */
void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *srna, void *data)
{
- tRKS_DSource *ds;
-
- /* sanity checks
- * - we must have somewhere to output the data
- * - we must have both srna+data (and with id too optionally), or id by itself only
- */
- if (dsources == NULL)
- return;
- if (ELEM(NULL, srna, data) && (id == NULL))
- return;
-
- /* allocate new elem, and add to the list */
- ds = MEM_callocN(sizeof(tRKS_DSource), "tRKS_DSource");
- BLI_addtail(dsources, ds);
-
- /* depending on what data we have, create using ID or full pointer call */
- if (srna && data)
- RNA_pointer_create(id, srna, data, &ds->ptr);
- else
- RNA_id_pointer_create(id, &ds->ptr);
+ tRKS_DSource *ds;
+
+ /* sanity checks
+ * - we must have somewhere to output the data
+ * - we must have both srna+data (and with id too optionally), or id by itself only
+ */
+ if (dsources == NULL)
+ return;
+ if (ELEM(NULL, srna, data) && (id == NULL))
+ return;
+
+ /* allocate new elem, and add to the list */
+ ds = MEM_callocN(sizeof(tRKS_DSource), "tRKS_DSource");
+ BLI_addtail(dsources, ds);
+
+ /* depending on what data we have, create using ID or full pointer call */
+ if (srna && data)
+ RNA_pointer_create(id, srna, data, &ds->ptr);
+ else
+ RNA_id_pointer_create(id, &ds->ptr);
}
/* KeyingSet Operations (Insert/Delete Keyframes) ------------ */
@@ -903,198 +907,216 @@ void ANIM_relative_keyingset_add_source(ListBase *dsources, ID *id, StructRNA *s
*/
short ANIM_validate_keyingset(bContext *C, ListBase *dsources, KeyingSet *ks)
{
- /* sanity check */
- if (ks == NULL)
- return 0;
-
- /* if relative Keying Sets, poll and build up the paths */
- if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
- KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
-
- /* clear all existing paths
- * NOTE: BKE_keyingset_free() frees all of the paths for the KeyingSet, but not the set itself
- */
- BKE_keyingset_free(ks);
-
- /* get the associated 'type info' for this KeyingSet */
- if (ksi == NULL)
- return MODIFYKEY_MISSING_TYPEINFO;
- /* TODO: check for missing callbacks! */
-
- /* check if it can be used in the current context */
- if (ksi->poll(ksi, C)) {
- /* if a list of data sources are provided, run a special iterator over them,
- * otherwise, just continue per normal
- */
- if (dsources)
- RKS_ITER_overrides_list(ksi, C, ks, dsources);
- else
- ksi->iter(ksi, C, ks);
-
- /* if we don't have any paths now, then this still qualifies as invalid context */
- // FIXME: we need some error conditions (to be retrieved from the iterator why this failed!)
- if (BLI_listbase_is_empty(&ks->paths))
- return MODIFYKEY_INVALID_CONTEXT;
- }
- else {
- /* poll callback tells us that KeyingSet is useless in current context */
- // FIXME: the poll callback needs to give us more info why
- return MODIFYKEY_INVALID_CONTEXT;
- }
- }
-
- /* succeeded; return 0 to tag error free */
- return 0;
+ /* sanity check */
+ if (ks == NULL)
+ return 0;
+
+ /* if relative Keying Sets, poll and build up the paths */
+ if ((ks->flag & KEYINGSET_ABSOLUTE) == 0) {
+ KeyingSetInfo *ksi = ANIM_keyingset_info_find_name(ks->typeinfo);
+
+ /* clear all existing paths
+ * NOTE: BKE_keyingset_free() frees all of the paths for the KeyingSet, but not the set itself
+ */
+ BKE_keyingset_free(ks);
+
+ /* get the associated 'type info' for this KeyingSet */
+ if (ksi == NULL)
+ return MODIFYKEY_MISSING_TYPEINFO;
+ /* TODO: check for missing callbacks! */
+
+ /* check if it can be used in the current context */
+ if (ksi->poll(ksi, C)) {
+ /* if a list of data sources are provided, run a special iterator over them,
+ * otherwise, just continue per normal
+ */
+ if (dsources)
+ RKS_ITER_overrides_list(ksi, C, ks, dsources);
+ else
+ ksi->iter(ksi, C, ks);
+
+ /* if we don't have any paths now, then this still qualifies as invalid context */
+ // FIXME: we need some error conditions (to be retrieved from the iterator why this failed!)
+ if (BLI_listbase_is_empty(&ks->paths))
+ return MODIFYKEY_INVALID_CONTEXT;
+ }
+ else {
+ /* poll callback tells us that KeyingSet is useless in current context */
+ // FIXME: the poll callback needs to give us more info why
+ return MODIFYKEY_INVALID_CONTEXT;
+ }
+ }
+
+ /* succeeded; return 0 to tag error free */
+ return 0;
}
/* Determine which keying flags apply based on the override flags */
-static short keyingset_apply_keying_flags(const short base_flags, const short overrides, const short own_flags)
+static short keyingset_apply_keying_flags(const short base_flags,
+ const short overrides,
+ const short own_flags)
{
- /* Pass through all flags by default (i.e. even not explicitly listed ones). */
- short result = base_flags;
-
- /* The logic for whether a keying flag applies is as follows:
- * - If the flag in question is set in "overrides", that means that the
- * status of that flag in "own_flags" is used
- * - If however the flag isn't set, then its value in "base_flags" is used
- * instead (i.e. no override)
- */
+ /* Pass through all flags by default (i.e. even not explicitly listed ones). */
+ short result = base_flags;
+
+ /* The logic for whether a keying flag applies is as follows:
+ * - If the flag in question is set in "overrides", that means that the
+ * status of that flag in "own_flags" is used
+ * - If however the flag isn't set, then its value in "base_flags" is used
+ * instead (i.e. no override)
+ */
#define APPLY_KEYINGFLAG_OVERRIDE(kflag) \
- if (overrides & kflag) { \
- result &= ~kflag; \
- result |= (own_flags & kflag); \
- }
-
- /* Apply the flags one by one...
- * (See rna_def_common_keying_flags() for the supported flags)
- */
- APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_NEEDED)
- APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_MATRIX)
- APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_XYZ2RGB)
+ if (overrides & kflag) { \
+ result &= ~kflag; \
+ result |= (own_flags & kflag); \
+ }
+
+ /* Apply the flags one by one...
+ * (See rna_def_common_keying_flags() for the supported flags)
+ */
+ APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_NEEDED)
+ APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_MATRIX)
+ APPLY_KEYINGFLAG_OVERRIDE(INSERTKEY_XYZ2RGB)
#undef APPLY_KEYINGFLAG_OVERRIDE
- return result;
+ return result;
}
/* Given a KeyingSet and context info (if required), modify keyframes for the channels specified
* by the KeyingSet. This takes into account many of the different combinations of using KeyingSets.
* Returns the number of channels that keyframes were added to
*/
-int ANIM_apply_keyingset(bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
+int ANIM_apply_keyingset(
+ bContext *C, ListBase *dsources, bAction *act, KeyingSet *ks, short mode, float cfra)
{
- Depsgraph *depsgraph = CTX_data_depsgraph(C);
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
- ReportList *reports = CTX_wm_reports(C);
- KS_Path *ksp;
- ListBase nla_cache = {NULL, NULL};
- const short base_kflags = ANIM_get_keyframing_flags(scene, 1);
- const char *groupname = NULL;
- short kflag = 0, success = 0;
- char keytype = scene->toolsettings->keyframe_type;
-
- /* sanity checks */
- if (ks == NULL)
- return 0;
-
- /* get flags to use */
- if (mode == MODIFYKEY_MODE_INSERT) {
- /* use context settings as base */
- kflag = keyingset_apply_keying_flags(base_kflags, ks->keyingoverride, ks->keyingflag);
- }
- else if (mode == MODIFYKEY_MODE_DELETE)
- kflag = 0;
-
- /* if relative Keying Sets, poll and build up the paths */
- success = ANIM_validate_keyingset(C, dsources, ks);
-
- if (success != 0) {
- /* return error code if failed */
- return success;
- }
-
- /* apply the paths as specified in the KeyingSet now */
- for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
- int arraylen, i;
- short kflag2;
-
- /* skip path if no ID pointer is specified */
- if (ksp->id == NULL) {
- BKE_reportf(reports, RPT_WARNING,
- "Skipping path in keying set, as it has no ID (KS = '%s', path = '%s[%d]')",
- ks->name, ksp->rna_path, ksp->array_index);
- continue;
- }
-
- /* since keying settings can be defined on the paths too, apply the settings for this path first */
- kflag2 = keyingset_apply_keying_flags(kflag, ksp->keyingoverride, ksp->keyingflag);
-
- /* get pointer to name of group to add channels to */
- if (ksp->groupmode == KSP_GROUP_NONE)
- groupname = NULL;
- else if (ksp->groupmode == KSP_GROUP_KSNAME)
- groupname = ks->name;
- else
- groupname = ksp->group;
-
- /* init arraylen and i - arraylen should be greater than i so that
- * normal non-array entries get keyframed correctly
- */
- i = ksp->array_index;
- arraylen = i;
-
- /* get length of array if whole array option is enabled */
- if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
- PointerRNA id_ptr, ptr;
- PropertyRNA *prop;
-
- RNA_id_pointer_create(ksp->id, &id_ptr);
- if (RNA_path_resolve_property(&id_ptr, ksp->rna_path, &ptr, &prop)) {
- arraylen = RNA_property_array_length(&ptr, prop);
- /* start from start of array, instead of the previously specified index - T48020 */
- i = 0;
- }
- }
-
- /* we should do at least one step */
- if (arraylen == i)
- arraylen++;
-
- /* for each possible index, perform operation
- * - assume that arraylen is greater than index
- */
- for (; i < arraylen; i++) {
- /* action to take depends on mode */
- if (mode == MODIFYKEY_MODE_INSERT)
- success += insert_keyframe(bmain, depsgraph, reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, keytype, &nla_cache, kflag2);
- else if (mode == MODIFYKEY_MODE_DELETE)
- success += delete_keyframe(bmain, reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
- }
-
- /* set recalc-flags */
- switch (GS(ksp->id->name)) {
- case ID_OB: /* Object (or Object-Related) Keyframes */
- {
- Object *ob = (Object *)ksp->id;
-
- // XXX: only object transforms?
- DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
- break;
- }
- default:
- DEG_id_tag_update(ksp->id, ID_RECALC_ANIMATION_NO_FLUSH);
- break;
- }
-
- /* send notifiers for updates (this doesn't require context to work!) */
- WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
- }
-
- BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
-
- /* return the number of channels successfully affected */
- return success;
+ Depsgraph *depsgraph = CTX_data_depsgraph(C);
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+ ReportList *reports = CTX_wm_reports(C);
+ KS_Path *ksp;
+ ListBase nla_cache = {NULL, NULL};
+ const short base_kflags = ANIM_get_keyframing_flags(scene, 1);
+ const char *groupname = NULL;
+ short kflag = 0, success = 0;
+ char keytype = scene->toolsettings->keyframe_type;
+
+ /* sanity checks */
+ if (ks == NULL)
+ return 0;
+
+ /* get flags to use */
+ if (mode == MODIFYKEY_MODE_INSERT) {
+ /* use context settings as base */
+ kflag = keyingset_apply_keying_flags(base_kflags, ks->keyingoverride, ks->keyingflag);
+ }
+ else if (mode == MODIFYKEY_MODE_DELETE)
+ kflag = 0;
+
+ /* if relative Keying Sets, poll and build up the paths */
+ success = ANIM_validate_keyingset(C, dsources, ks);
+
+ if (success != 0) {
+ /* return error code if failed */
+ return success;
+ }
+
+ /* apply the paths as specified in the KeyingSet now */
+ for (ksp = ks->paths.first; ksp; ksp = ksp->next) {
+ int arraylen, i;
+ short kflag2;
+
+ /* skip path if no ID pointer is specified */
+ if (ksp->id == NULL) {
+ BKE_reportf(reports,
+ RPT_WARNING,
+ "Skipping path in keying set, as it has no ID (KS = '%s', path = '%s[%d]')",
+ ks->name,
+ ksp->rna_path,
+ ksp->array_index);
+ continue;
+ }
+
+ /* since keying settings can be defined on the paths too, apply the settings for this path first */
+ kflag2 = keyingset_apply_keying_flags(kflag, ksp->keyingoverride, ksp->keyingflag);
+
+ /* get pointer to name of group to add channels to */
+ if (ksp->groupmode == KSP_GROUP_NONE)
+ groupname = NULL;
+ else if (ksp->groupmode == KSP_GROUP_KSNAME)
+ groupname = ks->name;
+ else
+ groupname = ksp->group;
+
+ /* init arraylen and i - arraylen should be greater than i so that
+ * normal non-array entries get keyframed correctly
+ */
+ i = ksp->array_index;
+ arraylen = i;
+
+ /* get length of array if whole array option is enabled */
+ if (ksp->flag & KSP_FLAG_WHOLE_ARRAY) {
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+
+ RNA_id_pointer_create(ksp->id, &id_ptr);
+ if (RNA_path_resolve_property(&id_ptr, ksp->rna_path, &ptr, &prop)) {
+ arraylen = RNA_property_array_length(&ptr, prop);
+ /* start from start of array, instead of the previously specified index - T48020 */
+ i = 0;
+ }
+ }
+
+ /* we should do at least one step */
+ if (arraylen == i)
+ arraylen++;
+
+ /* for each possible index, perform operation
+ * - assume that arraylen is greater than index
+ */
+ for (; i < arraylen; i++) {
+ /* action to take depends on mode */
+ if (mode == MODIFYKEY_MODE_INSERT)
+ success += insert_keyframe(bmain,
+ depsgraph,
+ reports,
+ ksp->id,
+ act,
+ groupname,
+ ksp->rna_path,
+ i,
+ cfra,
+ keytype,
+ &nla_cache,
+ kflag2);
+ else if (mode == MODIFYKEY_MODE_DELETE)
+ success += delete_keyframe(
+ bmain, reports, ksp->id, act, groupname, ksp->rna_path, i, cfra, kflag2);
+ }
+
+ /* set recalc-flags */
+ switch (GS(ksp->id->name)) {
+ case ID_OB: /* Object (or Object-Related) Keyframes */
+ {
+ Object *ob = (Object *)ksp->id;
+
+ // XXX: only object transforms?
+ DEG_id_tag_update(&ob->id, ID_RECALC_TRANSFORM | ID_RECALC_GEOMETRY);
+ break;
+ }
+ default:
+ DEG_id_tag_update(ksp->id, ID_RECALC_ANIMATION_NO_FLUSH);
+ break;
+ }
+
+ /* send notifiers for updates (this doesn't require context to work!) */
+ WM_main_add_notifier(NC_ANIMATION | ND_KEYFRAME | NA_ADDED, NULL);
+ }
+
+ BKE_animsys_free_nla_keyframing_context_cache(&nla_cache);
+
+ /* return the number of channels successfully affected */
+ return success;
}
/* ************************************************** */