diff options
author | Bastien Montagne <montagne29@wanadoo.fr> | 2016-07-12 01:01:38 +0300 |
---|---|---|
committer | Bastien Montagne <montagne29@wanadoo.fr> | 2016-07-12 01:07:44 +0300 |
commit | cfbd605567f48229a923df382baf6db98fbafc61 (patch) | |
tree | d4218c49672047d6c3b37517034660b3b5dcd966 /source/blender/editors/animation | |
parent | 71a57a37b2eebbed53b5335019287b4df9c30519 (diff) | |
parent | 7212ebd09f9720883581221be923ae5e97ff5d76 (diff) |
Merge branch 'master' into blender2.8
Conflicts:
intern/cycles/blender/addon/ui.py
source/blender/blenkernel/BKE_particle.h
source/blender/blenkernel/intern/dynamicpaint.c
source/blender/blenkernel/intern/library.c
source/blender/blenkernel/intern/object.c
source/blender/blenkernel/intern/particle.c
source/blender/blenkernel/intern/particle_distribute.c
source/blender/blenkernel/intern/texture.c
source/blender/editors/object/object_add.c
source/blender/editors/object/object_relations.c
source/blender/editors/physics/particle_edit.c
source/blender/editors/physics/particle_object.c
source/blender/editors/transform/transform_snap_object.c
Diffstat (limited to 'source/blender/editors/animation')
-rw-r--r-- | source/blender/editors/animation/anim_channels_edit.c | 12 | ||||
-rw-r--r-- | source/blender/editors/animation/anim_filter.c | 198 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframes_draw.c | 171 | ||||
-rw-r--r-- | source/blender/editors/animation/keyframes_edit.c | 10 |
4 files changed, 290 insertions, 101 deletions
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c index b690695ae69..edc258003fb 100644 --- a/source/blender/editors/animation/anim_channels_edit.c +++ b/source/blender/editors/animation/anim_channels_edit.c @@ -2352,7 +2352,7 @@ static void borderselect_anim_channels(bAnimContext *ac, rcti *rect, short selec } else { ymin = 0.0f; - ymax = (float)(-ACHANNEL_HEIGHT); + ymax = (float)(-ACHANNEL_HEIGHT(ac)); } /* convert border-region to view coordinates */ @@ -2368,7 +2368,7 @@ static void borderselect_anim_channels(bAnimContext *ac, rcti *rect, short selec if (ac->datatype == ANIMCONT_NLA) ymin = ymax - NLACHANNEL_STEP(snla); else - ymin = ymax - ACHANNEL_STEP; + ymin = ymax - ACHANNEL_STEP(ac); /* if channel is within border-select region, alter it */ if (!((ymax < rectf.ymin) || (ymin > rectf.ymax))) { @@ -2569,7 +2569,7 @@ static int animchannels_channel_get(bAnimContext *ac, const int mval[2]) 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, 0, (float)ACHANNEL_HEIGHT_HALF, x, y, NULL, &channel_index); + 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; @@ -2701,6 +2701,10 @@ static int mouse_anim_channels(bContext *C, bAnimContext *ac, int channel_index, 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 != sce->obedit) + ED_object_editmode_exit(C, EM_FREEDATA | EM_FREEUNDO | EM_WAITCURSOR | EM_DO_UNDO); + notifierFlags |= (ND_ANIMCHAN | NA_SELECTED); break; } @@ -2983,7 +2987,7 @@ static int animchannels_mouseclick_invoke(bContext *C, wmOperator *op, const wmE * 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, 0, (float)ACHANNEL_HEIGHT_HALF, x, y, NULL, &channel_index); + 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); diff --git a/source/blender/editors/animation/anim_filter.c b/source/blender/editors/animation/anim_filter.c index 554abc6e552..26f2a3ebf9c 100644 --- a/source/blender/editors/animation/anim_filter.c +++ b/source/blender/editors/animation/anim_filter.c @@ -70,6 +70,7 @@ #include "DNA_world_types.h" #include "DNA_gpencil_types.h" #include "DNA_object_types.h" +#include "DNA_userdef_types.h" #include "MEM_guardedalloc.h" @@ -96,9 +97,30 @@ #include "ED_anim_api.h" #include "ED_markers.h" +#include "UI_resources.h" /* for TH_KEYFRAME_SCALE lookup */ + /* ************************************************************ */ /* Blender Context <-> Animation Context mapping */ +/* ----------- Private Stuff - General -------------------- */ + +/* 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 theem settings methods can only handle chars. + */ + ac->yscale_fac = btheme->tact.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 ------------- */ /* Get shapekey data being edited (for Action Editor -> ShapeKey mode) */ @@ -351,6 +373,9 @@ bool ANIM_animdata_get_context(const bContext *C, bAnimContext *ac) 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); @@ -1241,7 +1266,7 @@ static size_t animfilter_action(bAnimContext *ac, ListBase *anim_data, bDopeShee /* 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) && (act->id.lib)) + if ((filter_mode & ANIMFILTER_FOREDIT) && ID_IS_LINKED_DATABLOCK(act)) return 0; /* do groups */ @@ -2633,11 +2658,97 @@ static size_t animdata_filter_dopesheet_scene(bAnimContext *ac, ListBase *anim_d 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, Scene *scene, 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 ((scene->lay & (ob->lay | base->lay)) == 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; + } + + /* check selection and object type filters */ + if ((ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (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->filterflag & ADS_FILTER_ONLYOBGROUP) { + if (BKE_group_object_exists(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); + + 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, Scene *scene, 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(&scene->base); + size_t num_bases = 0; + + Base **sorted_bases = MEM_mallocN(sizeof(Base *) * tot_bases, "Dopesheet Usable Sorted Bases"); + for (Base *base = scene->base.first; base; base = base->next) { + if (animdata_filter_base_is_ok(ads, scene, 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) { - Scene *sce = (Scene *)ads->source; - Base *base; + Scene *scene = (Scene *)ads->source; size_t items = 0; /* check that we do indeed have a scene */ @@ -2657,56 +2768,45 @@ static size_t animdata_filter_dopesheet(bAnimContext *ac, ListBase *anim_data, b } /* scene-linked animation - e.g. world, compositing nodes, scene anim (including sequencer currently) */ - items += animdata_filter_dopesheet_scene(ac, anim_data, ads, sce, filter_mode); - - /* loop over all bases (i.e.objects) in the scene */ - for (base = sce->base.first; base; base = base->next) { - /* check if there's an object (all the relevant checks are done in the ob-function) */ - if (base->object) { - 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 ((sce->lay & (ob->lay | base->lay)) == 0) continue; - - /* outliner restrict-flag */ - if (ob->restrictflag & OB_RESTRICT_VIEW) continue; - } - - /* 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)) - continue; + 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 behaviour 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) && + (scene->base.first != scene->base.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, scene, 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); } - /* check selection and object type filters */ - if ( (ads->filterflag & ADS_FILTER_ONLYSEL) && !((base->flag & SELECT) /*|| (base == sce->basact)*/) ) { - /* only selected should be shown */ - continue; - } + // TODO: store something to validate whether any changes are needed? - /* 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->filterflag & ADS_FILTER_ONLYOBGROUP) { - if (BKE_group_object_exists(ads->filter_grp, ob) == 0) - continue; + /* 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 = scene->base.first; base; base = base->next) { + if (animdata_filter_base_is_ok(ads, scene, 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); } - - /* since we're still here, this object should be usable */ - items += animdata_filter_dopesheet_ob(ac, anim_data, ads, base, filter_mode); } } diff --git a/source/blender/editors/animation/keyframes_draw.c b/source/blender/editors/animation/keyframes_draw.c index 6f1883cff55..6e776953356 100644 --- a/source/blender/editors/animation/keyframes_draw.c +++ b/source/blender/editors/animation/keyframes_draw.c @@ -40,6 +40,7 @@ #include "MEM_guardedalloc.h" #include "BLI_dlrbTree.h" +#include "BLI_math.h" #include "BLI_utildefines.h" #include "DNA_anim_types.h" @@ -282,6 +283,9 @@ static ActKeyBlock *bezts_to_new_actkeyblock(BezTriple *prev, BezTriple *beztn) ab->sel = (BEZT_ISSEL_ANY(prev) || BEZT_ISSEL_ANY(beztn)) ? SELECT : 0; ab->modified = 1; + if (BEZKEYTYPE(beztn) == BEZT_KEYTYPE_MOVEHOLD) + ab->flag |= ACTKEYBLOCK_FLAG_MOVING_HOLD; + return ab; } @@ -305,16 +309,28 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, BezTriple *first_bezt } - /* check if block needed - same value(s)? - * -> firstly, handles must have same central value as each other - * -> secondly, handles which control that section of the curve must be constant - */ + /* check if block needed */ if (prev == NULL) return; - if (IS_EQF(beztn->vec[1][1], prev->vec[1][1]) == 0) return; - - if (IS_EQF(beztn->vec[1][1], beztn->vec[0][1]) == 0) return; - if (IS_EQF(prev->vec[1][1], prev->vec[2][1]) == 0) return; + 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) + return; + } + else { + /* 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]) == 0) return; + + if (IS_EQF(beztn->vec[1][1], beztn->vec[0][1]) == 0) return; + if (IS_EQF(prev->vec[1][1], prev->vec[2][1]) == 0) return; + } /* if there are no blocks already, just add as root */ if (blocks->root == NULL) { @@ -340,7 +356,13 @@ static void add_bezt_to_keyblocks_list(DLRBT_Tree *blocks, BezTriple *first_bezt */ if (IS_EQT(ab->start, prev->vec[1][0], BEZT_BINARYSEARCH_THRESH)) { /* set selection status and 'touched' status */ - if (BEZT_ISSEL_ANY(beztn)) ab->sel = SELECT; + if (BEZT_ISSEL_ANY(beztn)) + ab->sel = SELECT; + + /* XXX: only when the first one was a moving hold? */ + if (BEZKEYTYPE(beztn) == BEZT_KEYTYPE_MOVEHOLD) + ab->flag |= ACTKEYBLOCK_FLAG_MOVING_HOLD; + ab->modified++; /* done... no need to insert */ @@ -485,7 +507,27 @@ void draw_keyframe_shape(float x, float y, float xscale, float hsize, short sel, /* tweak size of keyframe shape according to type of keyframe * - 'proper' keyframes have key_type = 0, so get drawn at full size */ - hsize -= 0.5f * key_type; + switch (key_type) { + case BEZT_KEYTYPE_KEYFRAME: /* must be full size */ + break; + + case BEZT_KEYTYPE_BREAKDOWN: /* slightly smaller than normal keyframe */ + hsize *= 0.85f; + break; + + case BEZT_KEYTYPE_MOVEHOLD: /* slightly smaller than normal keyframes (but by less than for breakdowns) */ + //hsize *= 0.72f; + hsize *= 0.95f; + break; + + case BEZT_KEYTYPE_EXTREME: /* slightly larger */ + hsize *= 1.2f; + break; + + default: + hsize -= 0.5f * key_type; + break; + } /* adjust view transform before starting */ glTranslatef(x, y, 0.0f); @@ -518,6 +560,15 @@ void draw_keyframe_shape(float x, float y, float xscale, float hsize, short sel, else UI_GetThemeColor4fv(TH_KEYTYPE_JITTER, inner_col); break; } + case BEZT_KEYTYPE_MOVEHOLD: /* similar to traditional keyframes, but different... */ + { + /* XXX: Should these get their own theme options instead? */ + if (sel) UI_GetThemeColorShade4fv(TH_STRIP_SELECT, 35, inner_col); + else UI_GetThemeColorShade4fv(TH_STRIP, 50, inner_col); + + inner_col[3] = 1.0f; /* full opacity, to avoid problems with visual glitches */ + break; + } case BEZT_KEYTYPE_KEYFRAME: /* traditional yellowish frames (default theme) */ default: { @@ -557,13 +608,16 @@ void draw_keyframe_shape(float x, float y, float xscale, float hsize, short sel, glTranslatef(-x, -y, 0.0f); } -static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, float ypos, short channelLocked) +static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, float ypos, float yscale_fac, bool channelLocked) { ActKeyColumn *ak; ActKeyBlock *ab; float alpha; float xscale; - float iconsize = U.widget_unit / 4.0f; + + const float iconsize = (U.widget_unit / 4.0f) * yscale_fac; + const float mhsize = iconsize * 0.7f; + glEnable(GL_BLEND); /* get View2D scaling factor */ @@ -576,6 +630,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa /* draw keyblocks */ if (blocks) { float sel_color[4], unsel_color[4]; + float sel_mhcol[4], unsel_mhcol[4]; /* cache colours first */ UI_GetThemeColor4fv(TH_STRIP_SELECT, sel_color); @@ -584,16 +639,32 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa sel_color[3] *= alpha; unsel_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; + /* NOTE: the tradeoff for changing colors between each draw is dwarfed by the cost of checking validity */ for (ab = blocks->first; ab; ab = ab->next) { if (actkeyblock_is_valid(ab, keys)) { - /* draw block */ - if (ab->sel) - glColor4fv(sel_color); - else - glColor4fv(unsel_color); - - glRectf(ab->start, ypos - iconsize, ab->end, ypos + iconsize); + if (ab->flag & ACTKEYBLOCK_FLAG_MOVING_HOLD) { + /* draw "moving hold" long-keyframe block - slightly smaller */ + if (ab->sel) + glColor4fv(sel_mhcol); + else + glColor4fv(unsel_mhcol); + + glRectf(ab->start, ypos - mhsize, ab->end, ypos + mhsize); + } + else { + /* draw standard long-keyframe block */ + if (ab->sel) + glColor4fv(sel_color); + else + glColor4fv(unsel_color); + + glRectf(ab->start, ypos - iconsize, ab->end, ypos + iconsize); + } } } } @@ -619,7 +690,7 @@ static void draw_keylist(View2D *v2d, DLRBT_Tree *keys, DLRBT_Tree *blocks, floa /* *************************** Channel Drawing Funcs *************************** */ -void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos) +void draw_summary_channel(View2D *v2d, bAnimContext *ac, float ypos, float yscale_fac) { DLRBT_Tree keys, blocks; @@ -631,13 +702,13 @@ void draw_summary_channel(View2D *v2d, bAnimContext *ac, 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, yscale_fac, false); BLI_dlrbTree_free(&keys); BLI_dlrbTree_free(&blocks); } -void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos) +void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, float ypos, float yscale_fac) { DLRBT_Tree keys, blocks; @@ -649,13 +720,13 @@ void draw_scene_channel(View2D *v2d, bDopeSheet *ads, Scene *sce, 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, yscale_fac, false); BLI_dlrbTree_free(&keys); BLI_dlrbTree_free(&blocks); } -void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos) +void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, float ypos, float yscale_fac) { DLRBT_Tree keys, blocks; @@ -667,19 +738,19 @@ void draw_object_channel(View2D *v2d, bDopeSheet *ads, Object *ob, 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, yscale_fac, false); BLI_dlrbTree_free(&keys); BLI_dlrbTree_free(&blocks); } -void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos) +void draw_fcurve_channel(View2D *v2d, AnimData *adt, FCurve *fcu, float ypos, float yscale_fac) { DLRBT_Tree keys, blocks; - short locked = (fcu->flag & FCURVE_PROTECTED) || - ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) || - ((adt && adt->action) && (adt->action->id.lib)); + bool locked = (fcu->flag & FCURVE_PROTECTED) || + ((fcu->grp) && (fcu->grp->flag & AGRP_PROTECTED)) || + ((adt && adt->action) && ID_IS_LINKED_DATABLOCK(adt->action)); BLI_dlrbTree_init(&keys); BLI_dlrbTree_init(&blocks); @@ -689,18 +760,18 @@ 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, locked); + draw_keylist(v2d, &keys, &blocks, ypos, yscale_fac, locked); BLI_dlrbTree_free(&keys); BLI_dlrbTree_free(&blocks); } -void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos) +void draw_agroup_channel(View2D *v2d, AnimData *adt, bActionGroup *agrp, float ypos, float yscale_fac) { DLRBT_Tree keys, blocks; - short locked = (agrp->flag & AGRP_PROTECTED) || - ((adt && adt->action) && (adt->action->id.lib)); + bool locked = (agrp->flag & AGRP_PROTECTED) || + ((adt && adt->action) && ID_IS_LINKED_DATABLOCK(adt->action)); BLI_dlrbTree_init(&keys); BLI_dlrbTree_init(&blocks); @@ -710,17 +781,17 @@ 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, locked); + draw_keylist(v2d, &keys, &blocks, ypos, yscale_fac, locked); BLI_dlrbTree_free(&keys); BLI_dlrbTree_free(&blocks); } -void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos) +void draw_action_channel(View2D *v2d, AnimData *adt, bAction *act, float ypos, float yscale_fac) { DLRBT_Tree keys, blocks; - short locked = (act && act->id.lib != NULL); + bool locked = (act && ID_IS_LINKED_DATABLOCK(act)); BLI_dlrbTree_init(&keys); BLI_dlrbTree_init(&blocks); @@ -730,13 +801,13 @@ 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, locked); + draw_keylist(v2d, &keys, &blocks, ypos, yscale_fac, locked); BLI_dlrbTree_free(&keys); BLI_dlrbTree_free(&blocks); } -void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos) +void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos, float yscale_fac) { DLRBT_Tree keys; @@ -746,38 +817,42 @@ void draw_gpencil_channel(View2D *v2d, bDopeSheet *ads, bGPdata *gpd, float ypos BLI_dlrbTree_linkedlist_sync(&keys); - draw_keylist(v2d, &keys, NULL, ypos, 0); + draw_keylist(v2d, &keys, NULL, ypos, yscale_fac, false); BLI_dlrbTree_free(&keys); } -void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos) +void draw_gpl_channel(View2D *v2d, bDopeSheet *ads, bGPDlayer *gpl, float ypos, float yscale_fac) { DLRBT_Tree keys; + bool locked = (gpl->flag & GP_LAYER_LOCKED) != 0; + BLI_dlrbTree_init(&keys); gpl_to_keylist(ads, gpl, &keys); BLI_dlrbTree_linkedlist_sync(&keys); - draw_keylist(v2d, &keys, NULL, ypos, (gpl->flag & GP_LAYER_LOCKED)); + draw_keylist(v2d, &keys, NULL, ypos, yscale_fac, locked); BLI_dlrbTree_free(&keys); } -void draw_masklay_channel(View2D *v2d, bDopeSheet *ads, MaskLayer *masklay, float ypos) +void draw_masklay_channel(View2D *v2d, bDopeSheet *ads, MaskLayer *masklay, float ypos, float yscale_fac) { DLRBT_Tree keys; - + + bool locked = (masklay->flag & MASK_LAYERFLAG_LOCKED) != 0; + BLI_dlrbTree_init(&keys); - + mask_to_keylist(ads, masklay, &keys); - + BLI_dlrbTree_linkedlist_sync(&keys); - - draw_keylist(v2d, &keys, NULL, ypos, (masklay->flag & MASK_LAYERFLAG_LOCKED)); - + + draw_keylist(v2d, &keys, NULL, ypos, yscale_fac, locked); + BLI_dlrbTree_free(&keys); } diff --git a/source/blender/editors/animation/keyframes_edit.c b/source/blender/editors/animation/keyframes_edit.c index 7b35a154fc8..4571df0f077 100644 --- a/source/blender/editors/animation/keyframes_edit.c +++ b/source/blender/editors/animation/keyframes_edit.c @@ -1208,6 +1208,13 @@ static short set_keytype_jitter(KeyframeEditData *UNUSED(ked), BezTriple *bezt) return 0; } +static short set_keytype_moving_hold(KeyframeEditData *UNUSED(ked), BezTriple *bezt) +{ + 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) { @@ -1221,6 +1228,9 @@ KeyframeEditFunc ANIM_editkeyframes_keytype(short code) case BEZT_KEYTYPE_JITTER: /* jitter keyframe */ return set_keytype_jitter; + case BEZT_KEYTYPE_MOVEHOLD: /* moving hold */ + return set_keytype_moving_hold; + case BEZT_KEYTYPE_KEYFRAME: /* proper keyframe */ default: return set_keytype_keyframe; |