diff options
author | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-07-21 03:12:05 +0400 |
---|---|---|
committer | Tamito Kajiyama <rd6t-kjym@asahi-net.or.jp> | 2012-07-21 03:12:05 +0400 |
commit | 3b012c041f1fb7b78eddcf1f93288cf7a86ab8d6 (patch) | |
tree | cead235bff7687610b1372e709e742ef70692dcb /source/blender/editors/animation | |
parent | 5a581c1fd116c51df13e09c5c320feba48d069bb (diff) | |
parent | 16516238e2b25ce53144c2dcea5323dc7313b724 (diff) |
Merged changes in the trunk up to revision 49090.
Diffstat (limited to 'source/blender/editors/animation')
-rw-r--r-- | source/blender/editors/animation/anim_channels_defines.c | 54 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_filter.c | 53 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_markers.c | 8 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_ops.c | 1 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframes_draw.c | 21 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframing.c | 157 |
7 files changed, 227 insertions, 68 deletions
diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index 6331dd51527..e890b8f2aba 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -852,7 +852,7 @@ static int acf_group_setting_flag(bAnimContext *ac, int setting, short *neg) // *neg = 1; - if we change this to edtiability return AGRP_PROTECTED; - case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */ + case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */ *neg = 1; return AGRP_NOTVISIBLE; } @@ -940,7 +940,7 @@ static int acf_fcurve_setting_flag(bAnimContext *UNUSED(ac), int setting, short // *neg = 1; - if we change this to edtiability return FCURVE_PROTECTED; - case ACHANNEL_SETTING_VISIBLE: /* visiblity - graph editor */ + case ACHANNEL_SETTING_VISIBLE: /* visibility - graph editor */ return FCURVE_VISIBLE; default: /* unsupported */ @@ -2585,11 +2585,11 @@ static bAnimChannelType ACF_GPL = 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 */ @@ -2619,7 +2619,7 @@ static short acf_mask_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem *UNU case ACHANNEL_SETTING_SELECT: case ACHANNEL_SETTING_EXPAND: return 1; - + default: return 0; } @@ -2630,15 +2630,15 @@ static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), int setting, short *n { /* clear extra return data first */ *neg = 0; - + switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ return AGRP_SELECTED; - + case ACHANNEL_SETTING_EXPAND: /* expanded */ return MASK_ANIMF_EXPAND; } - + /* this shouldn't happen */ return 0; } @@ -2647,7 +2647,7 @@ static int acf_mask_setting_flag(bAnimContext *UNUSED(ac), int setting, short *n static void *acf_mask_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short *type) { Mask *mask = (Mask *)ale->data; - + /* all flags are just in mask->flag for now... */ return GET_ACF_FLAG_PTR(mask->flag, type); } @@ -2656,16 +2656,16 @@ static void *acf_mask_setting_ptr(bAnimListElem *ale, int UNUSED(setting), short static bAnimChannelType ACF_MASKDATA = { "Mask Datablock", /* type name */ - + 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_nameprop, /* 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 */ @@ -2677,7 +2677,7 @@ static bAnimChannelType ACF_MASKDATA = static void acf_masklay_name(bAnimListElem *ale, char *name) { MaskLayer *masklay = (MaskLayer *)ale->data; - + if (masklay && name) BLI_strncpy(name, masklay->name, ANIM_CHAN_NAME_SIZE); } @@ -2688,7 +2688,7 @@ static short acf_masklay_name_prop(bAnimListElem *ale, PointerRNA *ptr, Property if (ale->data) { RNA_pointer_create(ale->id, &RNA_MaskLayer, ale->data, ptr); *prop = RNA_struct_name_property(ptr->type); - + return (*prop != NULL); } @@ -2703,7 +2703,7 @@ static short acf_masklay_setting_valid(bAnimContext *UNUSED(ac), bAnimListElem * case ACHANNEL_SETTING_EXPAND: /* mask layers are more like F-Curves than groups */ case ACHANNEL_SETTING_VISIBLE: /* graph editor only */ return 0; - + /* always available */ default: return 1; @@ -2715,18 +2715,18 @@ static int acf_masklay_setting_flag(bAnimContext *UNUSED(ac), int setting, short { /* clear extra return data first */ *neg = 0; - + switch (setting) { case ACHANNEL_SETTING_SELECT: /* selected */ return MASK_LAYERFLAG_SELECT; - + // case ACHANNEL_SETTING_MUTE: /* muted */ // return GP_LAYER_HIDE; - + case ACHANNEL_SETTING_PROTECT: /* protected */ // *neg = 1; - if we change this to edtiability return MASK_LAYERFLAG_LOCKED; - + default: /* unsupported */ return 0; } @@ -2780,17 +2780,17 @@ static void ANIM_init_channel_typeinfo_data(void) animchannelTypeInfo[type++] = NULL; /* None */ animchannelTypeInfo[type++] = NULL; /* AnimData */ animchannelTypeInfo[type++] = NULL; /* Special */ - + 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_FILLACTD; /* Object Action Expander */ animchannelTypeInfo[type++] = &ACF_FILLDRIVERS; /* Drivers Expander */ - + animchannelTypeInfo[type++] = &ACF_DSMAT; /* Material Channel */ animchannelTypeInfo[type++] = &ACF_DSLAM; /* Lamp Channel */ animchannelTypeInfo[type++] = &ACF_DSCAM; /* Camera Channel */ @@ -2806,15 +2806,15 @@ static void ANIM_init_channel_typeinfo_data(void) animchannelTypeInfo[type++] = &ACF_DSLAT; /* Lattice Channel */ animchannelTypeInfo[type++] = &ACF_DSSPK; /* Speaker Channel */ animchannelTypeInfo[type++] = &ACF_DSLINESTYLE; /* LineStyle Channel */ - + animchannelTypeInfo[type++] = &ACF_SHAPEKEY; /* ShapeKey */ - + 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 */ - + // TODO: these types still need to be implemented!!! // probably need a few extra flags for these special cases... animchannelTypeInfo[type++] = NULL; /* NLA Track */ diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 81b6d77dd82..035641b2888 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -418,16 +418,16 @@ short ANIM_animdata_get_context(const bContext *C, bAnimContext *ac) * * For this to work correctly, a standard set of data needs to be available within the scope that this * gets called in: - * - ListBase anim_data; - * - bDopeSheet *ads; - * - bAnimListElem *ale; + * - ListBase anim_data; + * - bDopeSheet *ads; + * - bAnimListElem *ale; * - size_t items; * * - id: ID block which should have an AnimData pointer following it immediately, to use - * - adtOk: line or block of code to execute for AnimData-blocks case (usually ANIMDATA_ADD_ANIMDATA) - * - nlaOk: line or block of code to execute for NLA tracks+strips case - * - driversOk: line or block of code to execute for Drivers case - * - keysOk: line or block of code for Keyframes case + * - adtOk: line or block of code to execute for AnimData-blocks case (usually ANIMDATA_ADD_ANIMDATA) + * - nlaOk: line or block of code to execute for NLA tracks+strips case + * - driversOk: line or block of code to execute for Drivers case + * - keysOk: line or block of code for Keyframes case * * The checks for the various cases are as follows: * 0) top level: checks for animdata and also that all the F-Curves for the block will be visible @@ -1330,6 +1330,7 @@ static size_t animdata_filter_shapekey(bAnimContext *ac, ListBase *anim_data, Ke return items; } +/* Helper for Grease Pencil - layers within a datablock */ static size_t animdata_filter_gpencil_data(ListBase *anim_data, bGPdata *gpd, int filter_mode) { bGPDlayer *gpl; @@ -1396,6 +1397,7 @@ static size_t animdata_filter_gpencil(ListBase *anim_data, void *UNUSED(data), i 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); @@ -1412,18 +1414,6 @@ static size_t animdata_filter_mask_data(ListBase *anim_data, Mask *mask, const i if (!(filter_mode & ANIMFILTER_ACTIVE) || (masklay_act == masklay)) { /* add to list */ ANIMCHANNEL_NEW_CHANNEL(masklay, ANIMTYPE_MASKLAYER, mask); - - -// if (filter_mode & ANIMFILTER_TMP_PEEK) -// return 1; -// else { -// bAnimListElem *ale = make_new_animlistelem(masklay, channel_type, (ID *)owner_id); -// if (ale) { -// BLI_addtail(anim_data, ale); -// items ++; -// } -// } - } // } } @@ -1432,28 +1422,29 @@ static size_t animdata_filter_mask_data(ListBase *anim_data, Mask *mask, const i return items; } +/* Grab all mask data */ static size_t animdata_filter_mask(ListBase *anim_data, void *UNUSED(data), int filter_mode) { Mask *mask; size_t items = 0; - - /* for now, grab grease pencil datablocks directly from main */ + + /* for now, grab mask datablocks directly from main */ // XXX: this is not good... for (mask = G.main->mask.first; mask; mask = mask->id.next) { ListBase tmp_data = {NULL, NULL}; size_t tmp_items = 0; - - /* only show if gpd is used by something... */ + + /* only show if mask is used by something... */ if (ID_REAL_USERS(mask) < 1) continue; - - /* add gpencil animation channels */ + + /* 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 */ @@ -1461,14 +1452,14 @@ static size_t animdata_filter_mask(ListBase *anim_data, void *UNUSED(data), int /* add gpd as channel too (if for drawing, and it has layers) */ ANIMCHANNEL_NEW_CHANNEL(mask, ANIMTYPE_MASKDATABLOCK, NULL); } - + /* now add the list of collected channels */ BLI_movelisttolist(anim_data, &tmp_data); BLI_assert((tmp_data.first == tmp_data.last) && (tmp_data.first == NULL)); items += tmp_items; } } - + /* return the number of items added to the list */ return items; } @@ -2453,7 +2444,7 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, int filter_mo items += animfilter_action(ac, anim_data, ads, data, filter_mode, (ID *)obact); } break; - + case ANIMCONT_SHAPEKEY: /* 'ShapeKey Editor' */ { /* the check for the DopeSheet summary is included here since the summary works here too */ @@ -2468,14 +2459,14 @@ size_t ANIM_animdata_filter(bAnimContext *ac, ListBase *anim_data, int filter_mo items = animdata_filter_gpencil(anim_data, data, filter_mode); } break; - + case ANIMCONT_MASK: { if (animdata_filter_dopesheet_summary(ac, anim_data, filter_mode, &items)) items = animdata_filter_mask(anim_data, data, filter_mode); } break; - + case ANIMCONT_DOPESHEET: /* 'DopeSheet Editor' */ { /* the DopeSheet editor is the primary place where the DopeSheet summaries are useful */ diff --git a/source/blender/editors/animation/anim_intern.h b/source/blender/editors/animation/anim_intern.h index 7d1209a3033..cf84eb04b10 100644 --- a/source/blender/editors/animation/anim_intern.h +++ b/source/blender/editors/animation/anim_intern.h @@ -55,6 +55,7 @@ void ANIM_OT_keyframe_delete_v3d(struct wmOperatorType *ot); /* Keyframe managment operators for UI buttons (RMB menu). */ void ANIM_OT_keyframe_insert_button(struct wmOperatorType *ot); void ANIM_OT_keyframe_delete_button(struct wmOperatorType *ot); +void ANIM_OT_keyframe_clear_button(struct wmOperatorType *ot); /* .......... */ diff --git a/source/blender/editors/animation/anim_markers.c b/source/blender/editors/animation/anim_markers.c index ea344e7e332..96044e2408e 100644 --- a/source/blender/editors/animation/anim_markers.c +++ b/source/blender/editors/animation/anim_markers.c @@ -848,14 +848,14 @@ static int ed_marker_move_modal(bContext *C, wmOperator *op, wmEvent *evt) } if (evt->val == KM_PRESS) { - float vec[3]; - char str_tx[256]; + float vec; + char str_tx[NUM_STR_REP_LEN]; if (handleNumInput(&mm->num, evt)) { - applyNumInput(&mm->num, vec); + applyNumInput(&mm->num, &vec); outputNumInput(&mm->num, str_tx); - RNA_int_set(op->ptr, "frames", vec[0]); + RNA_int_set(op->ptr, "frames", vec); ed_marker_move_apply(op); // ed_marker_header_update(C, op, str, (int)vec[0]); // strcat(str, str_tx); diff --git a/source/blender/editors/animation/anim_ops.c b/source/blender/editors/animation/anim_ops.c index 119df33dd91..13741a99d99 100644 --- a/source/blender/editors/animation/anim_ops.c +++ b/source/blender/editors/animation/anim_ops.c @@ -294,6 +294,7 @@ void ED_operatortypes_anim(void) WM_operatortype_append(ANIM_OT_keyframe_delete_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_driver_button_add); diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 84711b97729..85731933168 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -674,15 +674,15 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa if (keys) { /* locked channels are less strongly shown, as feedback for locked channels in DopeSheet */ /* TODO: allow this opacity factor to be themed? */ - float kalpha = (channelLocked) ? 0.35f : 1.0f; - + float kalpha = (channelLocked) ? 0.25f : 1.0f; + for (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) == 0) continue; - + /* draw using OpenGL - uglier but faster */ /* NOTE1: a previous version of this didn't work nice for some intel cards * NOTE2: if we wanted to go back to icons, these are icon = (ak->sel & SELECT) ? ICON_SPACE2 : ICON_SPACE3; */ @@ -753,6 +753,10 @@ void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos) { DLRBT_Tree keys, blocks; + short locked = (fcu->flag & FCURVE_PROTECTED) || + ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) || + ((adt && adt->action) && (adt->action->id.lib)); + BLI_dlrbTree_init(&keys); BLI_dlrbTree_init(&blocks); @@ -761,7 +765,7 @@ void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos) BLI_dlrbTree_linkedlist_sync(&keys); BLI_dlrbTree_linkedlist_sync(&blocks); - draw_keylist(v2d, &keys, &blocks, ypos, (fcu->flag & FCURVE_PROTECTED)); + draw_keylist(v2d, &keys, &blocks, ypos, locked); BLI_dlrbTree_free(&keys); BLI_dlrbTree_free(&blocks); @@ -771,6 +775,9 @@ void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float y { DLRBT_Tree keys, blocks; + short locked = (agrp->flag & AGRP_PROTECTED) || + ((adt && adt->action) && (adt->action->id.lib)); + BLI_dlrbTree_init(&keys); BLI_dlrbTree_init(&blocks); @@ -779,7 +786,7 @@ void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float y BLI_dlrbTree_linkedlist_sync(&keys); BLI_dlrbTree_linkedlist_sync(&blocks); - draw_keylist(v2d, &keys, &blocks, ypos, (agrp->flag & AGRP_PROTECTED)); + draw_keylist(v2d, &keys, &blocks, ypos, locked); BLI_dlrbTree_free(&keys); BLI_dlrbTree_free(&blocks); @@ -789,6 +796,8 @@ void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos) { DLRBT_Tree keys, blocks; + short locked = (act->id.lib != 0); + BLI_dlrbTree_init(&keys); BLI_dlrbTree_init(&blocks); @@ -797,7 +806,7 @@ void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos) BLI_dlrbTree_linkedlist_sync(&keys); BLI_dlrbTree_linkedlist_sync(&blocks); - draw_keylist(v2d, &keys, &blocks, ypos, 0); + draw_keylist(v2d, &keys, &blocks, ypos, locked); BLI_dlrbTree_free(&keys); BLI_dlrbTree_free(&blocks); diff --git a/source/blender/editors/animation/keyframing.c b/source/blender/editors/animation/keyframing.c index 7600e1d4690..3ef686910e6 100644 --- a/source/blender/editors/animation/keyframing.c +++ b/source/blender/editors/animation/keyframing.c @@ -1079,6 +1079,91 @@ short delete_keyframe(ReportList *reports, ID *id, bAction *act, const char grou return ret; } +/* ************************************************** */ +/* KEYFRAME CLEAR */ + +/* Main Keyframing API call: + * Use this when validation of necessary animation data isn't necessary as it + * already exists. It will clear the current buttons fcurve(s). + * + * The flag argument is used for special settings that alter the behavior of + * the keyframe deletion. These include the quick refresh options. + */ +short clear_keyframe(ReportList *reports, ID *id, bAction *act, const char group[], const char rna_path[], int array_index, short 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(&id_ptr, rna_path, &ptr, &prop) == 0) || (prop == NULL)) { + 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\n", 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(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 ( (fcu->flag & FCURVE_PROTECTED) || ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) ) { + if (G.debug & G_DEBUG) + printf("WARNING: not deleting keyframe for locked F-Curve\n"); + continue; + } + + ANIM_fcurve_delete_from_animdata(NULL, adt, fcu); + + /* return success */ + ret++; + } + + /* return success/failure */ + return ret; +} + /* ******************************************* */ /* KEYFRAME MODIFICATION */ @@ -1584,6 +1669,78 @@ void ANIM_OT_keyframe_delete_button(wmOperatorType *ot) 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) +{ + Main *bmain = CTX_data_main(C); + PointerRNA ptr = {{NULL}}; + PropertyRNA *prop = NULL; + char *path; + short success = 0; + int a, index, length, all = RNA_boolean_get(op->ptr, "all"); + + /* try to insert keyframe using property retrieved from UI */ + uiContextActiveProperty(C, &ptr, &prop, &index); + + if (ptr.id.data && ptr.data && prop) { + path = RNA_path_from_ID_to_property(&ptr, prop); + + if (path) { + if (all) { + length = RNA_property_array_length(&ptr, prop); + + if (length) index = 0; + else length = 1; + } + else + length = 1; + + for (a = 0; a < length; a++) + success += clear_keyframe(op->reports, ptr.id.data, NULL, NULL, path, index + a, 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 */ + uiContextAnimUpdate(C); + + DAG_ids_flush_update(bmain, 0); + + /* send notifiers that keyframes have been changed */ + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, 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"; + + /* callbacks */ + ot->exec = clear_key_button_exec; + ot->poll = modify_key_op_poll; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + /* properties */ + RNA_def_boolean(ot->srna, "all", 1, "All", "Clear keyframes from all elements of the array"); +} + /* ******************************************* */ /* AUTO KEYFRAME */ |