Proportional editing support for the action editor.
authorAntony Riakiotakis <kalast@gmail.com>
Tue, 7 Apr 2015 14:45:29 +0000 (16:45 +0200)
committerAntony Riakiotakis <kalast@gmail.com>
Tue, 7 Apr 2015 18:49:47 +0000 (20:49 +0200)
There are a few things here which are not so nice:

* Position of proportional edit circle is not centered on data
(difficult to predict positions here since those are completely custom,
 will probably be positioned at center of area later instead)

* Result is flushed to curve handles only at the end of the transform,
so if people have the graph editor open they will see handles lagging behind.

release/scripts/startup/bl_ui/space_dopesheet.py
source/blender/editors/space_action/action_ops.c
source/blender/editors/transform/transform.c
source/blender/editors/transform/transform_constraints.c
source/blender/editors/transform/transform_conversions.c
source/blender/editors/transform/transform_generics.c

index bb08a7c392e1d1362f4b5b9ab085a71f1a3a834e..843cf41b07c6a8e1db45f2819d2e8127653a2d6e 100644 (file)
@@ -105,6 +105,7 @@ class DOPESHEET_HT_header(Header):
         layout = self.layout
 
         st = context.space_data
+        toolsettings = context.tool_settings
 
         row = layout.row(align=True)
         row.template_header()
@@ -133,6 +134,11 @@ class DOPESHEET_HT_header(Header):
             # filters which will work here and are useful (especially for character animation)
             dopesheet_filter(layout, context, genericFiltersOnly=True)
 
+        row = layout.row(align=True)
+        row.prop(toolsettings, "proportional_edit", icon_only=True)
+        if toolsettings.proportional_edit != 'DISABLED':
+            row.prop(toolsettings, "proportional_edit_falloff", icon_only=True)
+
         # Grease Pencil mode doesn't need snapping, as it's frame-aligned only
         if st.mode != 'GPENCIL':
             layout.prop(st, "auto_snap", text="")
index 9ad0931a957c4ccbb8e1ccbf5d4b95d194c6f3fc..0f21446cc3d2676fb1d888bca1bfcc45f5fb9a3f 100644 (file)
@@ -202,7 +202,6 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
        WM_keymap_add_item(keymap, "ACTION_OT_keyframe_type", RKEY, KM_PRESS, 0, 0); 
        
        /* destructive */
-       WM_keymap_add_item(keymap, "ACTION_OT_clean", OKEY, KM_PRESS, 0, 0);
        WM_keymap_add_item(keymap, "ACTION_OT_sample", OKEY, KM_PRESS, KM_SHIFT, 0);
        
        WM_keymap_add_item(keymap, "ACTION_OT_delete", XKEY, KM_PRESS, 0, 0);
@@ -241,6 +240,11 @@ static void action_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
        /* transform system */
        transform_keymap_for_space(keyconf, keymap, SPACE_ACTION);
        
+       kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle_enum", OKEY, KM_PRESS, 0, 0);
+       RNA_string_set(kmi->ptr, "data_path", "tool_settings.proportional_edit");
+       RNA_string_set(kmi->ptr, "value_1", "DISABLED");
+       RNA_string_set(kmi->ptr, "value_2", "ENABLED");
+
        /* special markers hotkeys for anim editors: see note in definition of this function */
        ED_marker_keymap_animedit_conflictfree(keymap);
 }
index 44063335dbe2aabb5d102c6ac9de97602edf1a9c..17f1d6112b2a4ed2c6d5162fa0afc125cde9f783 100644 (file)
@@ -2095,6 +2095,12 @@ bool initTransform(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
                //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
                t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), helpline_poll, drawHelpline, t);
        }
+       else if (t->spacetype == SPACE_ACTION) {
+               unit_m3(t->spacemtx);
+               t->draw_handle_view = ED_region_draw_cb_activate(t->ar->type, drawTransformView, t, REGION_DRAW_POST_VIEW);
+               //t->draw_handle_pixel = ED_region_draw_cb_activate(t->ar->type, drawTransformPixel, t, REGION_DRAW_POST_PIXEL);
+               t->draw_handle_cursor = WM_paint_cursor_activate(CTX_wm_manager(C), helpline_poll, drawHelpline, t);
+       }
        else
                unit_m3(t->spacemtx);
 
@@ -7518,6 +7524,7 @@ static void initTimeTranslate(TransInfo *t)
 static void headerTimeTranslate(TransInfo *t, char str[MAX_INFO_LEN])
 {
        char tvec[NUM_STR_REP_LEN * 3];
+       int ofs = 0;
 
        /* if numeric input is active, use results from that, otherwise apply snapping to result */
        if (hasNumInput(&t->num)) {
@@ -7553,7 +7560,11 @@ static void headerTimeTranslate(TransInfo *t, char str[MAX_INFO_LEN])
                        BLI_snprintf(&tvec[0], NUM_STR_REP_LEN, "%.4f", val);
        }
 
-       BLI_snprintf(str, MAX_INFO_LEN, IFACE_("DeltaX: %s"), &tvec[0]);
+       ofs += BLI_snprintf(str, MAX_INFO_LEN, IFACE_("DeltaX: %s"), &tvec[0]);
+
+       if (t->flag & T_PROP_EDIT_ALL) {
+               ofs += BLI_snprintf(str + ofs, MAX_INFO_LEN - ofs, IFACE_(" Proportional size: %.2f"), t->prop_size);
+       }
 }
 
 static void applyTimeTranslateValue(TransInfo *t, float UNUSED(sval))
@@ -7590,7 +7601,7 @@ static void applyTimeTranslateValue(TransInfo *t, float UNUSED(sval))
                        }
 
                        val = BKE_nla_tweakedit_remap(adt, td->ival, NLATIME_CONVERT_MAP);
-                       val += deltax;
+                       val += deltax * td->factor;
                        *(td->val) = BKE_nla_tweakedit_remap(adt, val, NLATIME_CONVERT_UNMAP);
                }
                else {
index bcd66f56c5321ace5fab7d02aa4d1db04ff91d5c..03d626fe17972606e58795e65f164be12ed38f5a 100644 (file)
@@ -765,7 +765,7 @@ void drawPropCircle(const struct bContext *C, TransInfo *t)
                        }
                        glScalef(1.0f / aspx, 1.0f / aspy, 1.0f);
                }
-               else if (t->spacetype == SPACE_IPO) {
+               else if (ELEM(t->spacetype, SPACE_IPO, SPACE_ACTION)) {
                        /* only scale y */
                        rcti *mask = &t->ar->v2d.mask;
                        rctf *datamask = &t->ar->v2d.cur;
index 6124dab343f1fbb012d2e89acb60d5d7de58b2dc..23648c242f70c65d18fd1a9e86e9fbed0554f943 100644 (file)
@@ -3328,10 +3328,10 @@ static void posttrans_action_clean(bAnimContext *ac, bAction *act)
 /* ----------------------------- */
 
 /* fully select selected beztriples, but only include if it's on the right side of cfra */
-static int count_fcurve_keys(FCurve *fcu, char side, float cfra)
+static int count_fcurve_keys(FCurve *fcu, char side, float cfra, bool propedit)
 {
        BezTriple *bezt;
-       int i, count = 0;
+       int i, count = 0, count_all = 0;
 
        if (ELEM(NULL, fcu, fcu->bezt))
                return count;
@@ -3341,20 +3341,22 @@ static int count_fcurve_keys(FCurve *fcu, char side, float cfra)
                if (bezt->f2 & SELECT) {
                        /* no need to adjust the handle selection since they are assumed
                         * selected (like graph editor with SIPO_NOHANDLES) */
-                       if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
-                               count += 1;
-                       }
+                       if (FrameOnMouseSide(side, bezt->vec[1][0], cfra))
+                               count++;
                }
+               count_all++;
        }
 
-       return count;
+       if (propedit && count > 0)
+               return count_all;
+       else return count;
 }
 
 /* fully select selected beztriples, but only include if it's on the right side of cfra */
-static int count_gplayer_frames(bGPDlayer *gpl, char side, float cfra)
+static int count_gplayer_frames(bGPDlayer *gpl, char side, float cfra, bool propedit)
 {
        bGPDframe *gpf;
-       int count = 0;
+       int count = 0, count_all = 0;
        
        if (gpl == NULL)
                return count;
@@ -3365,16 +3367,20 @@ static int count_gplayer_frames(bGPDlayer *gpl, char side, float cfra)
                        if (FrameOnMouseSide(side, (float)gpf->framenum, cfra))
                                count++;
                }
+               count_all++;
        }
        
-       return count;
+       if (propedit && count > 0)
+               return count_all;
+       else
+               return count;
 }
 
 /* fully select selected beztriples, but only include if it's on the right side of cfra */
-static int count_masklayer_frames(MaskLayer *masklay, char side, float cfra)
+static int count_masklayer_frames(MaskLayer *masklay, char side, float cfra, bool propedit)
 {
        MaskLayerShape *masklayer_shape;
-       int count = 0;
+       int count = 0, count_all = 0;
 
        if (masklay == NULL)
                return count;
@@ -3385,9 +3391,13 @@ static int count_masklayer_frames(MaskLayer *masklay, char side, float cfra)
                        if (FrameOnMouseSide(side, (float)masklayer_shape->frame, cfra))
                                count++;
                }
+               count_all++;
        }
 
-       return count;
+       if (propedit && count > 0)
+               return count_all;
+       else
+               return count;
 }
 
 
@@ -3398,6 +3408,8 @@ static void TimeToTransData(TransData *td, float *time, AnimData *adt)
        td->val = time;
        td->ival = *(time);
 
+       td->center[0] = td->ival;
+
        /* store the AnimData where this keyframe exists as a keyframe of the
         * active action as td->extra.
         */
@@ -3411,7 +3423,7 @@ static void TimeToTransData(TransData *td, float *time, AnimData *adt)
  * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data
  * on the named side are used.
  */
-static TransData *ActionFCurveToTransData(TransData *td, TransData2D **td2dv, FCurve *fcu, AnimData *adt, char side, float cfra)
+static TransData *ActionFCurveToTransData(TransData *td, TransData2D **td2dv, FCurve *fcu, AnimData *adt, char side, float cfra, bool propedit)
 {
        BezTriple *bezt;
        TransData2D *td2d = *td2dv;
@@ -3422,11 +3434,14 @@ static TransData *ActionFCurveToTransData(TransData *td, TransData2D **td2dv, FC
 
        for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
                /* only add selected keyframes (for now, proportional edit is not enabled) */
-               if (bezt->f2 & SELECT) { /* note this MUST match count_fcurve_keys(), so can't use BEZSELECTED() macro */
+               if (propedit || (bezt->f2 & SELECT)) { /* note this MUST match count_fcurve_keys(), so can't use BEZSELECTED() macro */
                        /* only add if on the right 'side' of the current frame */
                        if (FrameOnMouseSide(side, bezt->vec[1][0], cfra)) {
                                TimeToTransData(td, bezt->vec[1], adt);
                                
+                               if (bezt->f2 & SELECT)
+                                       td->flag |= TD_SELECTED;
+
                                /*set flags to move handles as necessary*/
                                td->flag |= TD_MOVEHANDLE1 | TD_MOVEHANDLE2;
                                td2d->h1 = bezt->vec[0];
@@ -3477,19 +3492,21 @@ void flushTransIntFrameActionData(TransInfo *t)
  * The 'side' argument is needed for the extend mode. 'B' = both sides, 'R'/'L' mean only data
  * on the named side are used.
  */
-static int GPLayerToTransData(TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl, char side, float cfra)
+static int GPLayerToTransData(TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl, char side, float cfra, bool propedit)
 {
        bGPDframe *gpf;
        int count = 0;
        
        /* check for select frames on right side of current frame */
        for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
-               if (gpf->flag & GP_FRAME_SELECT) {
+               if (propedit || (gpf->flag & GP_FRAME_SELECT)) {
                        if (FrameOnMouseSide(side, (float)gpf->framenum, cfra)) {
                                /* memory is calloc'ed, so that should zero everything nicely for us */
                                td->val = &tfd->val;
                                td->ival = (float)gpf->framenum;
                                
+                               td->center[0] = td->ival;
+
                                tfd->val = (float)gpf->framenum;
                                tfd->sdata = &gpf->framenum;
                                
@@ -3505,19 +3522,21 @@ static int GPLayerToTransData(TransData *td, tGPFtransdata *tfd, bGPDlayer *gpl,
 }
 
 /* refer to comment above #GPLayerToTransData, this is the same but for masks */
-static int MaskLayerToTransData(TransData *td, tGPFtransdata *tfd, MaskLayer *masklay, char side, float cfra)
+static int MaskLayerToTransData(TransData *td, tGPFtransdata *tfd, MaskLayer *masklay, char side, float cfra, bool propedit)
 {
        MaskLayerShape *masklay_shape;
        int count = 0;
 
        /* check for select frames on right side of current frame */
        for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) {
-               if (masklay_shape->flag & MASK_SHAPE_SELECT) {
+               if (propedit || (masklay_shape->flag & MASK_SHAPE_SELECT)) {
                        if (FrameOnMouseSide(side, (float)masklay_shape->frame, cfra)) {
                                /* memory is calloc'ed, so that should zero everything nicely for us */
                                td->val = &tfd->val;
                                td->ival = (float)masklay_shape->frame;
 
+                               td->center[0] = td->ival;
+
                                tfd->val = (float)masklay_shape->frame;
                                tfd->sdata = &masklay_shape->frame;
 
@@ -3539,15 +3558,16 @@ static void createTransActionData(bContext *C, TransInfo *t)
        TransData *td = NULL;
        TransData2D *td2d = NULL;
        tGPFtransdata *tfd = NULL;
-       
+
        bAnimContext ac;
        ListBase anim_data = {NULL, NULL};
        bAnimListElem *ale;
        int filter;
-       
+       const bool propedit = (t->flag & T_PROP_EDIT) != 0;
+
        int count = 0;
        float cfra;
-       
+
        /* determine what type of data we are operating on */
        if (ANIM_animdata_get_context(C, &ac) == 0)
                return;
@@ -3575,7 +3595,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
        /* loop 1: fully select ipo-keys and count how many BezTriples are selected */
        for (ale = anim_data.first; ale; ale = ale->next) {
                AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
-               
+               int adt_count = 0;
                /* convert current-frame to action-time (slightly less accurate, especially under
                 * higher scaling ratios, but is faster than converting all points)
                 */
@@ -3585,13 +3605,18 @@ static void createTransActionData(bContext *C, TransInfo *t)
                        cfra = (float)CFRA;
                
                if (ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE))
-                       count += count_fcurve_keys(ale->key_data, t->frame_side, cfra);
+                       adt_count = count_fcurve_keys(ale->key_data, t->frame_side, cfra, propedit);
                else if (ale->type == ANIMTYPE_GPLAYER)
-                       count += count_gplayer_frames(ale->data, t->frame_side, cfra);
+                       adt_count = count_gplayer_frames(ale->data, t->frame_side, cfra, propedit);
                else if (ale->type == ANIMTYPE_MASKLAYER)
-                       count += count_masklayer_frames(ale->data, t->frame_side, cfra);
+                       adt_count = count_masklayer_frames(ale->data, t->frame_side, cfra, propedit);
                else
                        BLI_assert(0);
+
+               if (adt_count > 0) {
+                       count += adt_count;
+                       ale->tag = true;
+               }
        }
        
        /* stop if trying to build list if nothing selected */
@@ -3628,11 +3653,22 @@ static void createTransActionData(bContext *C, TransInfo *t)
        
        /* loop 2: build transdata array */
        for (ale = anim_data.first; ale; ale = ale->next) {
+               AnimData *adt;
+
+               if (propedit && !ale->tag)
+                       continue;
+
+               adt = ANIM_nla_mapping_get(&ac, ale);
+               if (adt)
+                       cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+               else
+                       cfra = (float)CFRA;
+
                if (ale->type == ANIMTYPE_GPLAYER) {
                        bGPDlayer *gpl = (bGPDlayer *)ale->data;
                        int i;
                        
-                       i = GPLayerToTransData(td, tfd, gpl, t->frame_side, cfra);
+                       i = GPLayerToTransData(td, tfd, gpl, t->frame_side, cfra, propedit);
                        td += i;
                        tfd += i;
                }
@@ -3640,7 +3676,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
                        MaskLayer *masklay = (MaskLayer *)ale->data;
                        int i;
 
-                       i = MaskLayerToTransData(td, tfd, masklay, t->frame_side, cfra);
+                       i = MaskLayerToTransData(td, tfd, masklay, t->frame_side, cfra, propedit);
                        td += i;
                        tfd += i;
                }
@@ -3648,15 +3684,7 @@ static void createTransActionData(bContext *C, TransInfo *t)
                        AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
                        FCurve *fcu = (FCurve *)ale->key_data;
                        
-                       /* convert current-frame to action-time (slightly less accurate, especially under
-                        * higher scaling ratios, but is faster than converting all points)
-                        */
-                       if (adt)
-                               cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
-                       else
-                               cfra = (float)CFRA;
-                       
-                       td = ActionFCurveToTransData(td, &td2d, fcu, adt, t->frame_side, cfra);
+                       td = ActionFCurveToTransData(td, &td2d, fcu, adt, t->frame_side, cfra, propedit);
                }
        }
        
@@ -3685,6 +3713,107 @@ static void createTransActionData(bContext *C, TransInfo *t)
                *((float *)(t->customData) + 1) = max;
        }
 
+       /* calculate distances for proportional editing */
+       if (propedit) {
+               td = t->data;
+
+               for (ale = anim_data.first; ale; ale = ale->next) {
+                       AnimData *adt;
+
+                       /* F-Curve may not have any keyframes */
+                       if (!ale->tag)
+                               continue;
+
+                       adt = ANIM_nla_mapping_get(&ac, ale);
+                       if (adt)
+                               cfra = BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+                       else
+                               cfra = (float)CFRA;
+
+                       if (ale->type == ANIMTYPE_GPLAYER) {
+                               bGPDlayer *gpl = (bGPDlayer *)ale->data;
+                               bGPDframe *gpf;
+
+                               for (gpf = gpl->frames.first; gpf; gpf = gpf->next) {
+                                       if (gpf->flag & GP_FRAME_SELECT) {
+                                               td->dist = td->rdist = 0.0f;
+                                       }
+                                       else {
+                                               bGPDframe *gpf_iter;
+                                               float min = FLT_MAX;
+                                               for (gpf_iter = gpl->frames.first; gpf_iter; gpf_iter = gpf->next) {
+                                                       if (gpf_iter->flag & GP_FRAME_SELECT) {
+                                                               if (FrameOnMouseSide(t->frame_side, (float)gpf_iter->framenum, cfra)) {
+                                                                       float val = fabs(gpf->framenum - gpf_iter->framenum);
+                                                                       if (val < min)
+                                                                               min = val;
+                                                               }
+                                                       }
+                                               }
+                                               td->dist = td->rdist = min;
+                                       }
+                                       td++;
+                               }
+                       }
+                       else if (ale->type == ANIMTYPE_MASKLAYER) {
+                               MaskLayer *masklay = (MaskLayer *)ale->data;
+                               MaskLayerShape *masklay_shape;
+
+                               for (masklay_shape = masklay->splines_shapes.first; masklay_shape; masklay_shape = masklay_shape->next) {
+                                       if (FrameOnMouseSide(t->frame_side, (float)masklay_shape->frame, cfra)) {
+                                               if (masklay_shape->flag & MASK_SHAPE_SELECT) {
+                                                       td->dist = td->rdist = 0.0f;
+                                               }
+                                               else {
+                                                       MaskLayerShape *masklay_iter;
+                                                       float min = FLT_MAX;
+                                                       for (masklay_iter = masklay->splines_shapes.first; masklay_iter; masklay_iter = masklay_iter->next) {
+                                                               if (masklay_iter->flag & MASK_SHAPE_SELECT) {
+                                                                       if (FrameOnMouseSide(t->frame_side, (float)masklay_iter->frame, cfra)) {
+                                                                               float val = fabs(masklay_shape->frame - masklay_iter->frame);
+                                                                               if (val < min)
+                                                                                       min = val;
+                                                                       }
+                                                               }
+                                                       }
+                                                       td->dist = td->rdist = min;
+                                               }
+                                               td++;
+                                       }
+                               }
+                       }
+                       else {
+                               FCurve *fcu = (FCurve *)ale->key_data;
+                               BezTriple *bezt;
+                               int i;
+
+                               for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) {
+                                       if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) {
+                                               if (bezt->f2 & SELECT) {
+                                                       td->dist = td->rdist = 0.0f;
+                                               }
+                                               else {
+                                                       BezTriple *bezt_iter;
+                                                       int j;
+                                                       float min = FLT_MAX;
+                                                       for (j = 0, bezt_iter = fcu->bezt; j < fcu->totvert; j++, bezt_iter++) {
+                                                               if (bezt_iter->f2 & SELECT) {
+                                                                       if (FrameOnMouseSide(t->frame_side, (float)bezt_iter->vec[1][0], cfra)) {
+                                                                               float val = fabs(bezt->vec[1][0] - bezt_iter->vec[1][0]);
+                                                                               if (val < min)
+                                                                                       min = val;
+                                                                       }
+                                                               }
+                                                       }
+                                                       td->dist = td->rdist = min;
+                                               }
+                                               td++;
+                                       }
+                               }
+                       }
+               }
+       }
+
        /* cleanup temp list */
        ANIM_animdata_freelist(&anim_data);
 }
@@ -3787,7 +3916,7 @@ static bool graph_edit_use_local_center(TransInfo *t)
 }
 
 
-static void graph_key_shortest_dist(FCurve *fcu, TransData *td_start, TransData *td, bool use_handle)
+static void graph_key_shortest_dist(TransInfo *t, FCurve *fcu, TransData *td_start, TransData *td, int cfra, bool use_handle)
 {
        int j = 0;
        TransData *td_iter = td_start;
@@ -3795,15 +3924,17 @@ static void graph_key_shortest_dist(FCurve *fcu, TransData *td_start, TransData
        td->dist = FLT_MAX;
        for (; j < fcu->totvert; j++) {
                BezTriple *bezt = fcu->bezt + j;
-               const bool sel2 = (bezt->f2 & SELECT) != 0;
-               const bool sel1 = use_handle ? (bezt->f1 & SELECT) != 0 : sel2;
-               const bool sel3 = use_handle ? (bezt->f3 & SELECT) != 0 : sel2;
+               if (FrameOnMouseSide(t->frame_side, bezt->vec[1][0], cfra)) {
+                       const bool sel2 = (bezt->f2 & SELECT) != 0;
+                       const bool sel1 = use_handle ? (bezt->f1 & SELECT) != 0 : sel2;
+                       const bool sel3 = use_handle ? (bezt->f3 & SELECT) != 0 : sel2;
 
-               if (sel1 || sel2 || sel3) {
-                       td->dist = td->rdist = min_ff(td->dist, fabs(td_iter->center[0] - td->center[0]));
-               }
+                       if (sel1 || sel2 || sel3) {
+                               td->dist = td->rdist = min_ff(td->dist, fabs(td_iter->center[0] - td->center[0]));
+                       }
 
-               td_iter += 3;
+                       td_iter += 3;
+               }
        }
 }
 
@@ -4091,7 +4222,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
                                                td->dist = td->rdist =  0.0f;
                                        }
                                        else {
-                                               graph_key_shortest_dist(fcu, td_start, td, use_handle);
+                                               graph_key_shortest_dist(t, fcu, td_start, td, cfra, use_handle);
                                        }
                                        td++;
 
@@ -4099,7 +4230,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
                                                td->dist = td->rdist = 0.0f;
                                        }
                                        else {
-                                               graph_key_shortest_dist(fcu, td_start, td, use_handle);
+                                               graph_key_shortest_dist(t, fcu, td_start, td, cfra, use_handle);
                                        }
                                        td++;
 
@@ -4107,7 +4238,7 @@ static void createTransGraphEditData(bContext *C, TransInfo *t)
                                                td->dist = td->rdist = 0.0f;
                                        }
                                        else {
-                                               graph_key_shortest_dist(fcu, td_start, td, use_handle);
+                                               graph_key_shortest_dist(t, fcu, td_start, td, cfra, use_handle);
                                        }
                                        td++;
                                }
@@ -7725,6 +7856,12 @@ void createTransData(bContext *C, TransInfo *t)
        else if (t->spacetype == SPACE_ACTION) {
                t->flag |= T_POINTS | T_2D_EDIT;
                createTransActionData(C, t);
+
+               if (t->data && (t->flag & T_PROP_EDIT)) {
+                       sort_trans_data(t); // makes selected become first in array
+                       //set_prop_dist(t, false); /* don't do that, distance has been set in createTransActionData already */
+                       sort_trans_data_dist(t);
+               }
        }
        else if (t->spacetype == SPACE_NLA) {
                t->flag |= T_POINTS | T_2D_EDIT;
@@ -7741,7 +7878,7 @@ void createTransData(bContext *C, TransInfo *t)
 
                if (t->data && (t->flag & T_PROP_EDIT)) {
                        sort_trans_data(t); // makes selected become first in array
-                       //set_prop_dist(t, false); /* don't do that, distance has been set in createTransGraphEditData already */
+                       set_prop_dist(t, false); /* don't do that, distance has been set in createTransGraphEditData already */
                        sort_trans_data_dist(t);
                }
        }
index 0571fc399a629f4903b9a42b92dc2a682f7937e6..27a072c301bd49b6a7a28c0e1e619e4314435dca 100644 (file)
@@ -1320,7 +1320,7 @@ void initTransInfo(bContext *C, TransInfo *t, wmOperator *op, const wmEvent *eve
                        /* use settings from scene only if modal */
                        if (t->flag & T_MODAL) {
                                if ((t->options & CTX_NO_PET) == 0) {
-                                       if (t->spacetype == SPACE_IPO) {
+                                       if (ELEM(t->spacetype, SPACE_IPO, SPACE_ACTION)) {
                                                t->flag |= initTransInfo_edit_pet_to_flag(ts->proportional);
                                        }
                                        else if (t->obedit) {