2.5 - Assorted Animation UI/Editing Tweaks
Main Feature: * It is now possible to choose which AnimData block is the 'active' one for editing, and/or select them too. AnimData blocks are generally the dark blue and lighter-blue expanders (i.e. Scene, Object, Camera, Lamp, Curve, Armature, etc.) * Objects are no longer selected/deselected when AKEY is used to toggle selection of channels. This was getting a bit annoying. * Following on from selection of AnimData blocks, it is now possible to select/make active an AnimData block in the animation editors, and change the active action for that block via the 'Animation Data' panel in NLA Editor's properties region. --> Be aware that user-counts are not totally handled correctly there yet, so some funky behaviour might be seen... --> It is possible to assign a new action, or to assign an existing one, allowing to switch between actions as in the past with Actions/IPO Editors... Other tweaks: * Some code tweaks towards making the 'Euler Filter' feature for Graph Editor working sometime soon * Added some backend code for snapping the values of keyframes to a single value. Still need to work out some UI for it though. * Shuffled the code for ACT_OT_new() around, and removed the poll() callback so that it worked in NLA too. * Fixed some more notifier bugs with deleting bones and a few other editmode operations for Armatures.
This commit is contained in:
@@ -244,6 +244,8 @@ void BKE_animdata_make_local(AnimData *adt)
|
||||
/* Check if some given RNA Path needs fixing - free the given path and set a new one as appropriate */
|
||||
static char *rna_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *newName, char *oldpath)
|
||||
{
|
||||
|
||||
|
||||
return oldpath; // FIXME!!!
|
||||
}
|
||||
|
||||
@@ -264,7 +266,7 @@ static void fcurves_path_rename_fix (ID *owner_id, PointerRNA *modPtr, char *new
|
||||
|
||||
/* driver targets */
|
||||
for (dtar= driver->targets.first; dtar; dtar=dtar->next) {
|
||||
dtat->rna_path= rna_path_rename_fix(owner_id, modPtr, newName, dtar->rna_path);
|
||||
dtat->rna_path= rna_path_rename_fix(dtar->id, modPtr, newName, dtar->rna_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -762,7 +762,7 @@ static int acf_fillactd_setting_flag(int setting, short *neg)
|
||||
|
||||
switch (setting) {
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return ACT_SELECTED;
|
||||
return ADT_UI_SELECTED;
|
||||
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
*neg= 1;
|
||||
@@ -777,13 +777,18 @@ static int acf_fillactd_setting_flag(int setting, short *neg)
|
||||
static void *acf_fillactd_setting_ptr(bAnimListElem *ale, int setting, short *type)
|
||||
{
|
||||
bAction *act= (bAction *)ale->data;
|
||||
AnimData *adt= ale->adt;
|
||||
|
||||
/* clear extra return data first */
|
||||
*type= 0;
|
||||
|
||||
switch (setting) {
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
GET_ACF_FLAG_PTR(act->flag);
|
||||
if (adt) {
|
||||
GET_ACF_FLAG_PTR(adt->flag);
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
GET_ACF_FLAG_PTR(act->flag);
|
||||
@@ -1001,6 +1006,9 @@ static int acf_dsmat_setting_flag(int setting, short *neg)
|
||||
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
|
||||
*neg= 1;
|
||||
return ADT_CURVES_NOT_VISIBLE;
|
||||
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return ADT_UI_SELECTED;
|
||||
|
||||
default: /* unsupported */
|
||||
return 0;
|
||||
@@ -1019,6 +1027,7 @@ static void *acf_dsmat_setting_ptr(bAnimListElem *ale, int setting, short *type)
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
GET_ACF_FLAG_PTR(ma->flag);
|
||||
|
||||
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)
|
||||
@@ -1070,6 +1079,9 @@ static int acf_dslam_setting_flag(int setting, short *neg)
|
||||
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
|
||||
*neg= 1;
|
||||
return ADT_CURVES_NOT_VISIBLE;
|
||||
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return ADT_UI_SELECTED;
|
||||
|
||||
default: /* unsupported */
|
||||
return 0;
|
||||
@@ -1088,6 +1100,7 @@ static void *acf_dslam_setting_ptr(bAnimListElem *ale, int setting, short *type)
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
GET_ACF_FLAG_PTR(la->flag);
|
||||
|
||||
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)
|
||||
@@ -1139,6 +1152,9 @@ static int acf_dscam_setting_flag(int setting, short *neg)
|
||||
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
|
||||
*neg= 1;
|
||||
return ADT_CURVES_NOT_VISIBLE;
|
||||
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return ADT_UI_SELECTED;
|
||||
|
||||
default: /* unsupported */
|
||||
return 0;
|
||||
@@ -1157,6 +1173,7 @@ static void *acf_dscam_setting_ptr(bAnimListElem *ale, int setting, short *type)
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
GET_ACF_FLAG_PTR(ca->flag);
|
||||
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
case ACHANNEL_SETTING_MUTE: /* muted (for NLA only) */
|
||||
case ACHANNEL_SETTING_VISIBLE: /* visible (for Graph Editor only) */
|
||||
if (ca->adt)
|
||||
@@ -1208,6 +1225,9 @@ static int acf_dscur_setting_flag(int setting, short *neg)
|
||||
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
|
||||
*neg= 1;
|
||||
return ADT_CURVES_NOT_VISIBLE;
|
||||
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return ADT_UI_SELECTED;
|
||||
|
||||
default: /* unsupported */
|
||||
return 0;
|
||||
@@ -1226,6 +1246,7 @@ static void *acf_dscur_setting_ptr(bAnimListElem *ale, int setting, short *type)
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
GET_ACF_FLAG_PTR(cu->flag);
|
||||
|
||||
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)
|
||||
@@ -1277,6 +1298,9 @@ static int acf_dsskey_setting_flag(int setting, short *neg)
|
||||
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
|
||||
*neg= 1;
|
||||
return ADT_CURVES_NOT_VISIBLE;
|
||||
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return ADT_UI_SELECTED;
|
||||
|
||||
default: /* unsupported */
|
||||
return 0;
|
||||
@@ -1295,6 +1319,7 @@ static void *acf_dsskey_setting_ptr(bAnimListElem *ale, int setting, short *type
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
GET_ACF_FLAG_PTR(key->flag);
|
||||
|
||||
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)
|
||||
@@ -1346,6 +1371,9 @@ static int acf_dswor_setting_flag(int setting, short *neg)
|
||||
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
|
||||
*neg= 1;
|
||||
return ADT_CURVES_NOT_VISIBLE;
|
||||
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return ADT_UI_SELECTED;
|
||||
|
||||
default: /* unsupported */
|
||||
return 0;
|
||||
@@ -1364,6 +1392,7 @@ static void *acf_dswor_setting_ptr(bAnimListElem *ale, int setting, short *type)
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
GET_ACF_FLAG_PTR(wo->flag);
|
||||
|
||||
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)
|
||||
@@ -1415,6 +1444,9 @@ static int acf_dspart_setting_flag(int setting, short *neg)
|
||||
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
|
||||
*neg= 1;
|
||||
return ADT_CURVES_NOT_VISIBLE;
|
||||
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return ADT_UI_SELECTED;
|
||||
|
||||
default: /* unsupported */
|
||||
return 0;
|
||||
@@ -1433,6 +1465,7 @@ static void *acf_dspart_setting_ptr(bAnimListElem *ale, int setting, short *type
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
GET_ACF_FLAG_PTR(part->flag);
|
||||
|
||||
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)
|
||||
@@ -1485,6 +1518,9 @@ static int acf_dsmball_setting_flag(int setting, short *neg)
|
||||
*neg= 1;
|
||||
return ADT_CURVES_NOT_VISIBLE;
|
||||
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return ADT_UI_SELECTED;
|
||||
|
||||
default: /* unsupported */
|
||||
return 0;
|
||||
}
|
||||
@@ -1502,6 +1538,7 @@ static void *acf_dsmball_setting_ptr(bAnimListElem *ale, int setting, short *typ
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
GET_ACF_FLAG_PTR(mb->flag);
|
||||
|
||||
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)
|
||||
@@ -1553,6 +1590,9 @@ static int acf_dsarm_setting_flag(int setting, short *neg)
|
||||
case ACHANNEL_SETTING_VISIBLE: /* visible (only in Graph Editor) */
|
||||
*neg= 1;
|
||||
return ADT_CURVES_NOT_VISIBLE;
|
||||
|
||||
case ACHANNEL_SETTING_SELECT: /* selected */
|
||||
return ADT_UI_SELECTED;
|
||||
|
||||
default: /* unsupported */
|
||||
return 0;
|
||||
@@ -1571,6 +1611,7 @@ static void *acf_dsarm_setting_ptr(bAnimListElem *ale, int setting, short *type)
|
||||
case ACHANNEL_SETTING_EXPAND: /* expanded */
|
||||
GET_ACF_FLAG_PTR(arm->flag);
|
||||
|
||||
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)
|
||||
|
||||
@@ -91,6 +91,7 @@
|
||||
/* -------------------------- Exposed API ----------------------------------- */
|
||||
|
||||
/* 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, short datatype, int filter, void *channel_data, short channel_type)
|
||||
{
|
||||
ListBase anim_data = {NULL, NULL};
|
||||
@@ -130,11 +131,29 @@ void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int
|
||||
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_DSCUR:
|
||||
case ANIMTYPE_DSSKEY:
|
||||
case ANIMTYPE_DSWOR:
|
||||
case ANIMTYPE_DSPART:
|
||||
case ANIMTYPE_DSMBALL:
|
||||
case ANIMTYPE_DSARM:
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
/* set active flag */
|
||||
if (channel_data != NULL) {
|
||||
if (channel_data) {
|
||||
switch (channel_type) {
|
||||
case ANIMTYPE_GROUP:
|
||||
{
|
||||
@@ -154,6 +173,23 @@ void ANIM_set_active_channel (bAnimContext *ac, void *data, short datatype, int
|
||||
nlt->flag |= NLATRACK_ACTIVE;
|
||||
}
|
||||
break;
|
||||
|
||||
case ANIMTYPE_FILLACTD: /* Action Expander */
|
||||
case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
|
||||
case ANIMTYPE_DSLAM:
|
||||
case ANIMTYPE_DSCAM:
|
||||
case ANIMTYPE_DSCUR:
|
||||
case ANIMTYPE_DSSKEY:
|
||||
case ANIMTYPE_DSWOR:
|
||||
case ANIMTYPE_DSPART:
|
||||
case ANIMTYPE_DSMBALL:
|
||||
case ANIMTYPE_DSARM:
|
||||
{
|
||||
/* need to verify that this data is valid for now */
|
||||
if (ale->adt)
|
||||
ale->adt->flag |= ADT_UI_ACTIVE;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -174,7 +210,7 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
|
||||
int filter;
|
||||
|
||||
/* filter data */
|
||||
filter= ANIMFILTER_VISIBLE;
|
||||
filter= ANIMFILTER_VISIBLE|ANIMFILTER_CHANNELS;
|
||||
ANIM_animdata_filter(NULL, &anim_data, filter, data, datatype);
|
||||
|
||||
/* See if we should be selecting or deselecting */
|
||||
@@ -189,12 +225,10 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
|
||||
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;
|
||||
break;
|
||||
case ANIMTYPE_FILLACTD:
|
||||
if (ale->flag & ACT_SELECTED)
|
||||
sel= ACHANNEL_SETFLAG_CLEAR;
|
||||
#endif
|
||||
break;
|
||||
case ANIMTYPE_GROUP:
|
||||
if (ale->flag & AGRP_SELECTED)
|
||||
@@ -208,6 +242,22 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
|
||||
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_DSCUR:
|
||||
case ANIMTYPE_DSSKEY:
|
||||
case ANIMTYPE_DSWOR:
|
||||
case ANIMTYPE_DSPART:
|
||||
case ANIMTYPE_DSMBALL:
|
||||
case ANIMTYPE_DSARM:
|
||||
{
|
||||
if ((ale->adt) && (ale->adt->flag & ADT_UI_SELECTED))
|
||||
sel= ACHANNEL_SETFLAG_CLEAR;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -220,23 +270,26 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
|
||||
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);
|
||||
}
|
||||
break;
|
||||
case ANIMTYPE_FILLACTD:
|
||||
{
|
||||
bAction *act= (bAction *)ale->data;
|
||||
|
||||
ACHANNEL_SET_FLAG(act, sel, ACT_SELECTED);
|
||||
if (ob->adt) {
|
||||
ACHANNEL_SET_FLAG(ob, sel, ADT_UI_SELECTED);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
case ANIMTYPE_GROUP:
|
||||
{
|
||||
@@ -262,6 +315,25 @@ void ANIM_deselect_anim_channels (void *data, short datatype, short test, short
|
||||
nlt->flag &= ~NLATRACK_ACTIVE;
|
||||
}
|
||||
break;
|
||||
|
||||
case ANIMTYPE_FILLACTD: /* Action Expander */
|
||||
case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
|
||||
case ANIMTYPE_DSLAM:
|
||||
case ANIMTYPE_DSCAM:
|
||||
case ANIMTYPE_DSCUR:
|
||||
case ANIMTYPE_DSSKEY:
|
||||
case ANIMTYPE_DSWOR:
|
||||
case ANIMTYPE_DSPART:
|
||||
case ANIMTYPE_DSMBALL:
|
||||
case ANIMTYPE_DSARM:
|
||||
{
|
||||
/* 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1310,18 +1382,22 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
|
||||
}
|
||||
|
||||
/* 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_SELECT;
|
||||
@@ -1333,34 +1409,75 @@ static int mouse_anim_channels (bAnimContext *ac, float x, int channel_index, sh
|
||||
Scene *sce= (Scene *)ads->source;
|
||||
Base *base= (Base *)ale->data;
|
||||
Object *ob= base->object;
|
||||
AnimData *adt= ob->adt;
|
||||
|
||||
/* set selection status */
|
||||
if (selectmode == SELECT_INVERT) {
|
||||
/* swap select */
|
||||
base->flag ^= SELECT;
|
||||
ob->flag= base->flag;
|
||||
|
||||
if (adt) adt->flag ^= ADT_UI_SELECTED;
|
||||
}
|
||||
else {
|
||||
Base *b;
|
||||
|
||||
/* deleselect all */
|
||||
/* deselect all */
|
||||
// TODO: should this deselect all other types of channels too?
|
||||
for (b= sce->base.first; b; b= b->next) {
|
||||
b->flag &= ~SELECT;
|
||||
b->object->flag= b->flag;
|
||||
if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED|ADT_UI_ACTIVE);
|
||||
}
|
||||
|
||||
/* select object now */
|
||||
base->flag |= SELECT;
|
||||
ob->flag |= SELECT;
|
||||
if (adt) adt->flag |= ADT_UI_SELECTED;
|
||||
}
|
||||
|
||||
/* xxx should be ED_base_object_activate(), but we need context pointer for that... */
|
||||
//set_active_base(base);
|
||||
if ((adt) && (adt->flag & ADT_UI_SELECTED))
|
||||
adt->flag |= ADT_UI_ACTIVE;
|
||||
|
||||
notifierFlags |= ND_ANIMCHAN_SELECT;
|
||||
}
|
||||
break;
|
||||
|
||||
case ANIMTYPE_FILLACTD: /* Action Expander */
|
||||
case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
|
||||
case ANIMTYPE_DSLAM:
|
||||
case ANIMTYPE_DSCAM:
|
||||
case ANIMTYPE_DSCUR:
|
||||
case ANIMTYPE_DSSKEY:
|
||||
case ANIMTYPE_DSWOR:
|
||||
case ANIMTYPE_DSPART:
|
||||
case ANIMTYPE_DSMBALL:
|
||||
case ANIMTYPE_DSARM:
|
||||
{
|
||||
/* 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->data, ac->datatype, 0, 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_SELECT;
|
||||
}
|
||||
break;
|
||||
|
||||
case ANIMTYPE_GROUP:
|
||||
{
|
||||
bActionGroup *agrp= (bActionGroup *)ale->data;
|
||||
|
||||
@@ -413,7 +413,9 @@ short ANIM_animdata_get_context (const bContext *C, bAnimContext *ac)
|
||||
}\
|
||||
}
|
||||
|
||||
|
||||
/* 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) )
|
||||
|
||||
/* quick macro to test if an anim-channel (F-Curve, Group, etc.) is selected in an acceptable way */
|
||||
#define ANIMCHANNEL_SELOK(test_func) \
|
||||
@@ -980,10 +982,13 @@ static int animdata_filter_dopesheet_mats (ListBase *anim_data, bDopeSheet *ads,
|
||||
/* include material-expand widget? */
|
||||
// hmm... do we need to store the index of this material in the array anywhere?
|
||||
if (filter_mode & ANIMFILTER_CHANNELS) {
|
||||
ale= make_new_animlistelem(ma, ANIMTYPE_DSMAT, base, ANIMTYPE_OBJECT, (ID *)ma);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
/* check if filtering by active status */
|
||||
if ANIMCHANNEL_ACTIVEOK(ma) {
|
||||
ale= make_new_animlistelem(ma, ANIMTYPE_DSMAT, base, ANIMTYPE_OBJECT, (ID *)ma);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1037,11 +1042,14 @@ static int animdata_filter_dopesheet_particles (ListBase *anim_data, bDopeSheet
|
||||
|
||||
/* add particle settings? */
|
||||
if (FILTER_PART_OBJC(ob) || (filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
if ((filter_mode & ANIMFILTER_CHANNELS)){
|
||||
ale = make_new_animlistelem(psys->part, ANIMTYPE_DSPART, base, ANIMTYPE_OBJECT, (ID *)psys->part);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
if ((filter_mode & ANIMFILTER_CHANNELS)) {
|
||||
/* check if filtering by active status */
|
||||
if ANIMCHANNEL_ACTIVEOK(psys->part) {
|
||||
ale = make_new_animlistelem(psys->part, ANIMTYPE_DSPART, base, ANIMTYPE_OBJECT, (ID *)psys->part);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1117,9 +1125,12 @@ static int animdata_filter_dopesheet_obdata (ListBase *anim_data, bDopeSheet *ad
|
||||
expanded= EXPANDED_DRVD(adt);
|
||||
|
||||
/* include data-expand widget? */
|
||||
if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {
|
||||
ale= make_new_animlistelem(iat, type, base, ANIMTYPE_OBJECT, (ID *)iat);
|
||||
if (ale) BLI_addtail(anim_data, ale);
|
||||
if ((filter_mode & ANIMFILTER_CURVESONLY) == 0) {
|
||||
/* check if filtering by active status */
|
||||
if ANIMCHANNEL_ACTIVEOK(iat) {
|
||||
ale= make_new_animlistelem(iat, type, base, ANIMTYPE_OBJECT, (ID *)iat);
|
||||
if (ale) BLI_addtail(anim_data, ale);
|
||||
}
|
||||
}
|
||||
|
||||
/* add object-data animation channels? */
|
||||
@@ -1149,10 +1160,13 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
||||
if ((filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) == 0) {
|
||||
/* check if filtering by selection */
|
||||
if ANIMCHANNEL_SELOK((base->flag & SELECT)) {
|
||||
ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE, NULL);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
/* check if filtering by active status */
|
||||
if ANIMCHANNEL_ACTIVEOK(ob) {
|
||||
ale= make_new_animlistelem(base, ANIMTYPE_OBJECT, NULL, ANIMTYPE_NONE, (ID *)ob);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1233,10 +1247,13 @@ static int animdata_filter_dopesheet_ob (ListBase *anim_data, bDopeSheet *ads, B
|
||||
{ /* action (keyframes) */
|
||||
/* include shapekey-expand widget? */
|
||||
if ((filter_mode & ANIMFILTER_CHANNELS) && !(filter_mode & ANIMFILTER_CURVESONLY)) {
|
||||
ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
/* check if filtering by active status */
|
||||
if ANIMCHANNEL_ACTIVEOK(key) {
|
||||
ale= make_new_animlistelem(key, ANIMTYPE_DSSKEY, base, ANIMTYPE_OBJECT, (ID *)ob);
|
||||
if (ale) {
|
||||
BLI_addtail(anim_data, ale);
|
||||
items++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -461,6 +461,13 @@ static short snap_bezier_horizontal(BeztEditData *bed, BezTriple *bezt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static short snap_bezier_value(BeztEditData *bed, BezTriple *bezt)
|
||||
{
|
||||
/* value to snap to is stored in the custom data -> first float value slot */
|
||||
if (bezt->f2 & SELECT)
|
||||
bezt->vec[1][1]= bed->f1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
BeztEditFunc ANIM_editkeyframes_snap(short type)
|
||||
{
|
||||
@@ -476,6 +483,8 @@ BeztEditFunc ANIM_editkeyframes_snap(short type)
|
||||
return snap_bezier_nearestsec;
|
||||
case SNAP_KEYS_HORIZONTAL: /* snap handles to same value */
|
||||
return snap_bezier_horizontal;
|
||||
case SNAP_KEYS_VALUE: /* snap to given value */
|
||||
return snap_bezier_value;
|
||||
default: /* just in case */
|
||||
return snap_bezier_nearest;
|
||||
}
|
||||
|
||||
@@ -1736,7 +1736,7 @@ static int armature_delete_selected_exec(bContext *C, wmOperator *op)
|
||||
|
||||
ED_armature_sync_selection(arm->edbo);
|
||||
|
||||
WM_event_add_notifier(C, NC_OBJECT, obedit);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, obedit);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
@@ -3938,7 +3938,7 @@ static int armature_parent_clear_exec(bContext *C, wmOperator *op)
|
||||
ED_armature_sync_selection(arm->edbo);
|
||||
|
||||
/* note, notifier might evolve */
|
||||
WM_event_add_notifier(C, NC_OBJECT, ob);
|
||||
WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, ob);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
@@ -73,6 +73,7 @@ typedef enum eEditKeyframes_Snap {
|
||||
SNAP_KEYS_NEARSEC,
|
||||
SNAP_KEYS_NEARMARKER,
|
||||
SNAP_KEYS_HORIZONTAL,
|
||||
SNAP_KEYS_VALUE,
|
||||
} eEditKeyframes_Snap;
|
||||
|
||||
/* mirroring tools */
|
||||
|
||||
@@ -88,6 +88,44 @@
|
||||
|
||||
#include "action_intern.h"
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* ACTION MANAGEMENT */
|
||||
|
||||
/* ******************** New Action Operator *********************** */
|
||||
|
||||
static int act_new_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
bAction *action;
|
||||
|
||||
// XXX need to restore behaviour to copy old actions...
|
||||
action= add_empty_action("Action");
|
||||
|
||||
/* combined with RNA property, this will assign & increase user,
|
||||
so decrease here to compensate for that */
|
||||
action->id.us--;
|
||||
|
||||
/* set notifier that keyframes have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void ACT_OT_new (wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "New";
|
||||
ot->idname= "ACT_OT_new";
|
||||
ot->description= "Create new action.";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= act_new_exec;
|
||||
// NOTE: this is used in the NLA too...
|
||||
//ot->poll= ED_operator_action_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
/* KEYFRAME-RANGE STUFF */
|
||||
|
||||
@@ -1331,38 +1369,4 @@ void ACT_OT_mirror (wmOperatorType *ot)
|
||||
RNA_def_enum(ot->srna, "type", prop_actkeys_mirror_types, 0, "Type", "");
|
||||
}
|
||||
|
||||
/* ******************** New Action Operator *********************** */
|
||||
|
||||
static int act_new_exec(bContext *C, wmOperator *op)
|
||||
{
|
||||
bAction *action;
|
||||
|
||||
// XXX need to restore behaviour to copy old actions...
|
||||
action= add_empty_action("Action");
|
||||
|
||||
/* combined with RNA property, this will assign & increase user,
|
||||
so decrease here to compensate for that */
|
||||
action->id.us--;
|
||||
|
||||
/* set notifier that keyframes have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void ACT_OT_new (wmOperatorType *ot)
|
||||
{
|
||||
/* identifiers */
|
||||
ot->name= "New";
|
||||
ot->idname= "ACT_OT_new";
|
||||
ot->description= "Create new action.";
|
||||
|
||||
/* api callbacks */
|
||||
ot->exec= act_new_exec;
|
||||
ot->poll= ED_operator_action_active;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
}
|
||||
|
||||
/* ************************************************************************** */
|
||||
|
||||
@@ -858,9 +858,6 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri
|
||||
* - if the option to only show controls if the F-Curve is selected is enabled, we must obey this
|
||||
*/
|
||||
if (!(sipo->flag & SIPO_SELCUVERTSONLY) || (fcu->flag & FCURVE_SELECTED)) {
|
||||
/* enable blending to allow fading of curves */
|
||||
glEnable(GL_BLEND);
|
||||
|
||||
if (fcurve_needs_draw_fmodifier_controls(fcu, fcm)) {
|
||||
/* only draw controls if this is the active modifier */
|
||||
if ((fcu->flag & FCURVE_ACTIVE) && (fcm)) {
|
||||
@@ -874,7 +871,10 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri
|
||||
else if ( ((fcu->bezt) || (fcu->fpt)) && (fcu->totvert) ) {
|
||||
if (fcu->bezt) {
|
||||
/* only draw handles/vertices on keyframes */
|
||||
draw_fcurve_handles(sipo, ar, fcu);
|
||||
glEnable(GL_BLEND);
|
||||
draw_fcurve_handles(sipo, ar, fcu);
|
||||
glDisable(GL_BLEND);
|
||||
|
||||
draw_fcurve_vertices(sipo, ar, fcu);
|
||||
}
|
||||
else {
|
||||
@@ -882,9 +882,6 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri
|
||||
draw_fcurve_samples(sipo, ar, fcu);
|
||||
}
|
||||
}
|
||||
|
||||
/* restore settings */
|
||||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
/* undo mapping of keyframes for drawing if scaled F-Curve */
|
||||
|
||||
@@ -1296,8 +1296,7 @@ void GRAPH_OT_handle_type (wmOperatorType *ot)
|
||||
/* set of three euler-rotation F-Curves */
|
||||
typedef struct tEulerFilter {
|
||||
ID *id; /* ID-block which owns the channels */
|
||||
FCurve *fcu1, *fcu2, *fcu3; /* x,y,z rotation curves */
|
||||
int i1, i2, i3; /* current index for each curve */
|
||||
FCurve (*fcurves)[3]; /* 3 Pointers to F-Curves */
|
||||
} tEulerFilter;
|
||||
|
||||
static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op)
|
||||
@@ -1347,10 +1346,26 @@ static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op)
|
||||
if ((euf) && (ale->id != euf->id)) {
|
||||
|
||||
}
|
||||
else {
|
||||
/* just add to a new block */
|
||||
euf= MEM_callocN(sizeof(tEulerFilter), "tEulerFilter");
|
||||
BLI_addtail(&eulers, euf);
|
||||
|
||||
euf->id= ale->id;
|
||||
euf->fcurves[fcu->array_index]= fcu;
|
||||
}
|
||||
}
|
||||
BLI_freelistN(&anim_data);
|
||||
|
||||
// XXX for now
|
||||
return OPERATOR_CANCELLED;
|
||||
/* step 2: go through each set of curves, processing the values at each keyframe
|
||||
* - it is assumed that there must be a full set of keyframes at each keyframe position
|
||||
*/
|
||||
for (euf= eulers.first; euf; euf= euf->next) {
|
||||
|
||||
}
|
||||
BLI_freelistN(&eulers);
|
||||
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
void GRAPH_OT_euler_filter (wmOperatorType *ot)
|
||||
@@ -1789,7 +1804,7 @@ void GRAPH_OT_fmodifier_add (wmOperatorType *ot)
|
||||
/* api callbacks */
|
||||
ot->invoke= graph_fmodifier_add_invoke;
|
||||
ot->exec= graph_fmodifier_add_exec;
|
||||
ot->poll= graphop_active_fcurve_poll;
|
||||
ot->poll= graphop_selected_fcurve_poll;
|
||||
|
||||
/* flags */
|
||||
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
||||
|
||||
@@ -155,6 +155,7 @@ short fcurve_needs_draw_fmodifier_controls(struct FCurve *fcu, struct FModifier
|
||||
int graphop_visible_keyframes_poll(struct bContext *C);
|
||||
int graphop_editable_keyframes_poll(struct bContext *C);
|
||||
int graphop_active_fcurve_poll(struct bContext *C);
|
||||
int graphop_selected_fcurve_poll(struct bContext *C);
|
||||
|
||||
/* ***************************************** */
|
||||
/* graph_ops.c */
|
||||
|
||||
@@ -285,4 +285,34 @@ int graphop_active_fcurve_poll (bContext *C)
|
||||
return has_fcurve;
|
||||
}
|
||||
|
||||
/* has selected F-Curve that's editable */
|
||||
int graphop_selected_fcurve_poll (bContext *C)
|
||||
{
|
||||
bAnimContext ac;
|
||||
bAnimListElem *ale;
|
||||
ListBase anim_data = {NULL, NULL};
|
||||
ScrArea *sa= CTX_wm_area(C);
|
||||
int filter, items;
|
||||
short found = 0;
|
||||
|
||||
/* firstly, check if in Graph Editor */
|
||||
// TODO: also check for region?
|
||||
if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
|
||||
return 0;
|
||||
|
||||
/* try to init Anim-Context stuff ourselves and check */
|
||||
if (ANIM_animdata_get_context(C, &ac) == 0)
|
||||
return 0;
|
||||
|
||||
/* get the editable + selected F-Curves, and as long as we got some, we can return */
|
||||
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
|
||||
items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
|
||||
if (items == 0)
|
||||
return 0;
|
||||
|
||||
/* cleanup and return findings */
|
||||
BLI_freelistN(&anim_data);
|
||||
return found;
|
||||
}
|
||||
|
||||
/* ************************************************************** */
|
||||
|
||||
@@ -114,34 +114,69 @@ static int nla_panel_context(const bContext *C, PointerRNA *adt_ptr, PointerRNA
|
||||
if (ANIM_animdata_get_context(C, &ac) == 0)
|
||||
return 0;
|
||||
|
||||
/* extract list of active channel(s), of which we should only take the first one (expecting it to be an NLA track) */
|
||||
filter= (ANIMFILTER_VISIBLE|ANIMFILTER_ACTIVE);
|
||||
/* extract list of active channel(s), of which we should only take the first one
|
||||
* - we need the channels flag to get the active AnimData block when there are no NLA Tracks
|
||||
*/
|
||||
filter= (ANIMFILTER_VISIBLE|ANIMFILTER_ACTIVE|ANIMFILTER_CHANNELS);
|
||||
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
|
||||
|
||||
for (ale= anim_data.first; ale; ale= ale->next) {
|
||||
// TODO: need some way to select active animdata too...
|
||||
if (ale->type == ANIMTYPE_NLATRACK) {
|
||||
NlaTrack *nlt= (NlaTrack *)ale->data;
|
||||
AnimData *adt= ale->adt;
|
||||
|
||||
/* found it, now set the pointers */
|
||||
if (adt_ptr) {
|
||||
/* AnimData pointer */
|
||||
RNA_pointer_create(ale->id, &RNA_AnimData, adt, adt_ptr);
|
||||
switch (ale->type) {
|
||||
case ANIMTYPE_NLATRACK: /* NLA Track - The primary data type which should get caught */
|
||||
{
|
||||
NlaTrack *nlt= (NlaTrack *)ale->data;
|
||||
AnimData *adt= ale->adt;
|
||||
|
||||
/* found it, now set the pointers */
|
||||
if (adt_ptr) {
|
||||
/* AnimData pointer */
|
||||
RNA_pointer_create(ale->id, &RNA_AnimData, adt, adt_ptr);
|
||||
}
|
||||
if (nlt_ptr) {
|
||||
/* NLA-Track pointer */
|
||||
RNA_pointer_create(ale->id, &RNA_NlaTrack, nlt, nlt_ptr);
|
||||
}
|
||||
if (strip_ptr) {
|
||||
/* NLA-Strip pointer */
|
||||
NlaStrip *strip= BKE_nlastrip_find_active(nlt);
|
||||
RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, strip_ptr);
|
||||
}
|
||||
|
||||
found= 1;
|
||||
}
|
||||
if (nlt_ptr) {
|
||||
/* NLA-Track pointer */
|
||||
RNA_pointer_create(ale->id, &RNA_NlaTrack, nlt, nlt_ptr);
|
||||
}
|
||||
if (strip_ptr) {
|
||||
/* NLA-Strip pointer */
|
||||
NlaStrip *strip= BKE_nlastrip_find_active(nlt);
|
||||
RNA_pointer_create(ale->id, &RNA_NlaStrip, strip, strip_ptr);
|
||||
}
|
||||
|
||||
found= 1;
|
||||
break;
|
||||
break;
|
||||
|
||||
case ANIMTYPE_SCENE: /* Top-Level Widgets doubling up as datablocks */
|
||||
case ANIMTYPE_OBJECT:
|
||||
case ANIMTYPE_FILLACTD: /* Action Expander */
|
||||
case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
|
||||
case ANIMTYPE_DSLAM:
|
||||
case ANIMTYPE_DSCAM:
|
||||
case ANIMTYPE_DSCUR:
|
||||
case ANIMTYPE_DSSKEY:
|
||||
case ANIMTYPE_DSWOR:
|
||||
case ANIMTYPE_DSPART:
|
||||
case ANIMTYPE_DSMBALL:
|
||||
case ANIMTYPE_DSARM:
|
||||
{
|
||||
/* for these channels, we only do AnimData */
|
||||
if (ale->id && ale->adt) {
|
||||
if (adt_ptr) {
|
||||
/* AnimData pointer */
|
||||
RNA_pointer_create(ale->id, &RNA_AnimData, ale->adt, adt_ptr);
|
||||
|
||||
/* set found status to -1, since setting to 1 would break the loop
|
||||
* and potentially skip an active NLA-Track in some cases...
|
||||
*/
|
||||
found= -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (found > 0)
|
||||
break;
|
||||
}
|
||||
|
||||
/* free temp data */
|
||||
@@ -211,7 +246,7 @@ static void nla_panel_animdata (const bContext *C, Panel *pa)
|
||||
/* Active Action Properties ------------------------------------- */
|
||||
/* action */
|
||||
row= uiLayoutRow(layout, 1);
|
||||
uiTemplateID(row, (bContext *)C, &adt_ptr, "action", NULL /*"ACT_OT_new"*/, NULL, NULL /*"ACT_OT_unlink"*/); // XXX: need to make these operators
|
||||
uiTemplateID(row, (bContext *)C, &adt_ptr, "action", "ACT_OT_new", NULL, NULL /*"ACT_OT_unlink"*/); // XXX: need to make these operators
|
||||
|
||||
/* extrapolation */
|
||||
row= uiLayoutRow(layout, 1);
|
||||
|
||||
@@ -116,18 +116,22 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho
|
||||
}
|
||||
|
||||
/* action to take depends on what channel we've got */
|
||||
// WARNING: must keep this in sync with the equivalent function in anim_channels_edit.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_SELECT;
|
||||
@@ -139,6 +143,7 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho
|
||||
Scene *sce= (Scene *)ads->source;
|
||||
Base *base= (Base *)ale->data;
|
||||
Object *ob= base->object;
|
||||
AnimData *adt= ob->adt;
|
||||
|
||||
if (nlaedit_is_tweakmode_on(ac) == 0) {
|
||||
/* set selection status */
|
||||
@@ -146,23 +151,30 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho
|
||||
/* swap select */
|
||||
base->flag ^= SELECT;
|
||||
ob->flag= base->flag;
|
||||
|
||||
if (adt) adt->flag ^= ADT_UI_SELECTED;
|
||||
}
|
||||
else {
|
||||
Base *b;
|
||||
|
||||
/* deleselect all */
|
||||
/* deselect all */
|
||||
// TODO: should this deselect all other types of channels too?
|
||||
for (b= sce->base.first; b; b= b->next) {
|
||||
b->flag &= ~SELECT;
|
||||
b->object->flag= b->flag;
|
||||
if (b->object->adt) b->object->adt->flag &= ~(ADT_UI_SELECTED|ADT_UI_ACTIVE);
|
||||
}
|
||||
|
||||
/* select object now */
|
||||
base->flag |= SELECT;
|
||||
ob->flag |= SELECT;
|
||||
if (adt) adt->flag |= ADT_UI_SELECTED;
|
||||
}
|
||||
|
||||
/* xxx should be ED_base_object_activate(), but we need context pointer for that... */
|
||||
//set_active_base(base);
|
||||
if ((adt) && (adt->flag & ADT_UI_SELECTED))
|
||||
adt->flag |= ADT_UI_ACTIVE;
|
||||
|
||||
/* notifiers - channel was selected */
|
||||
notifierFlags |= ND_ANIMCHAN_SELECT;
|
||||
@@ -170,6 +182,39 @@ static int mouse_nla_channels (bAnimContext *ac, float x, int channel_index, sho
|
||||
}
|
||||
break;
|
||||
|
||||
case ANIMTYPE_FILLACTD: /* Action Expander */
|
||||
case ANIMTYPE_DSMAT: /* Datablock AnimData Expanders */
|
||||
case ANIMTYPE_DSLAM:
|
||||
case ANIMTYPE_DSCAM:
|
||||
case ANIMTYPE_DSCUR:
|
||||
case ANIMTYPE_DSSKEY:
|
||||
case ANIMTYPE_DSWOR:
|
||||
case ANIMTYPE_DSPART:
|
||||
case ANIMTYPE_DSMBALL:
|
||||
case ANIMTYPE_DSARM:
|
||||
{
|
||||
/* 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->data, ac->datatype, 0, 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_SELECT;
|
||||
}
|
||||
break;
|
||||
|
||||
case ANIMTYPE_NLATRACK:
|
||||
{
|
||||
NlaTrack *nlt= (NlaTrack *)ale->data;
|
||||
|
||||
@@ -763,6 +763,11 @@ typedef enum eAnimData_Flag {
|
||||
/* don't execute drivers */
|
||||
ADT_DRIVERS_DISABLED = (1<<11),
|
||||
|
||||
/* AnimData block is selected in UI */
|
||||
ADT_UI_SELECTED = (1<<14),
|
||||
/* AnimData block is active in UI */
|
||||
ADT_UI_ACTIVE = (1<<15),
|
||||
|
||||
/* F-Curves from this AnimData block are not visible in the Graph Editor */
|
||||
ADT_CURVES_NOT_VISIBLE = (1<<16),
|
||||
} eAnimData_Flag;
|
||||
|
||||
@@ -57,6 +57,12 @@ static int rna_AnimData_action_editable(PointerRNA *ptr)
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void rna_AnimData_action_set(PointerRNA *ptr, PointerRNA value)
|
||||
{
|
||||
AnimData *adt= (AnimData*)(ptr->data);
|
||||
adt->action= value.data;
|
||||
}
|
||||
|
||||
static void rna_ksPath_RnaPath_get(PointerRNA *ptr, char *value)
|
||||
{
|
||||
KS_Path *ksp= (KS_Path *)ptr->data;
|
||||
@@ -202,8 +208,11 @@ void rna_def_animdata(BlenderRNA *brna)
|
||||
|
||||
/* Active Action */
|
||||
prop= RNA_def_property(srna, "action", PROP_POINTER, PROP_NONE);
|
||||
RNA_def_property_ui_text(prop, "Action", "Active Action for this datablock.");
|
||||
RNA_def_property_pointer_funcs(prop, NULL, "rna_AnimData_action_set", NULL);
|
||||
RNA_def_property_flag(prop, PROP_EDITABLE); /* this flag as well as the dynamic test must be defined for this to be editable... */
|
||||
RNA_def_property_editable_func(prop, "rna_AnimData_action_editable");
|
||||
RNA_def_property_ui_text(prop, "Action", "Active Action for this datablock.");
|
||||
|
||||
|
||||
/* Active Action Settings */
|
||||
prop= RNA_def_property(srna, "action_extrapolation", PROP_ENUM, PROP_NONE);
|
||||
|
||||
@@ -239,7 +239,7 @@ void wm_event_do_notifiers(bContext *C)
|
||||
|
||||
if(G.rendering==0) { // XXX make lock in future, or separated derivedmesh users in scene
|
||||
|
||||
/* update all objects, ipos, matrices, displists, etc. Flags set by depgraph or manual,
|
||||
/* update all objects, drivers, matrices, displists, etc. Flags set by depgraph or manual,
|
||||
no layer check here, gets correct flushed */
|
||||
/* sets first, we allow per definition current scene to have dependencies on sets */
|
||||
if(scene->set) {
|
||||
|
||||
Reference in New Issue
Block a user