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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_graph')
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c23
-rw-r--r--source/blender/editors/space_graph/graph_draw.c34
-rw-r--r--source/blender/editors/space_graph/graph_edit.c90
-rw-r--r--source/blender/editors/space_graph/graph_intern.h4
-rw-r--r--source/blender/editors/space_graph/graph_ops.c18
-rw-r--r--source/blender/editors/space_graph/graph_select.c32
-rw-r--r--source/blender/editors/space_graph/graph_utils.c9
7 files changed, 142 insertions, 68 deletions
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index a2b64afdb15..e0b62722d57 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -165,9 +165,28 @@ static void graph_panel_properties(const bContext *C, Panel *pa)
RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr);
/* user-friendly 'name' for F-Curve */
- /* TODO: only show the path if this is invalid? */
col = uiLayoutColumn(layout, false);
- icon = getname_anim_fcurve(name, ale->id, fcu);
+ if (ale->type == ANIMTYPE_FCURVE) {
+ /* get user-friendly name for F-Curve */
+ icon = getname_anim_fcurve(name, ale->id, fcu);
+ }
+ else {
+ /* NLA Control Curve, etc. */
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+
+ /* get name */
+ if (acf && acf->name) {
+ acf->name(ale, name);
+ }
+ else {
+ strcpy(name, IFACE_("<invalid>"));
+ icon = ICON_ERROR;
+ }
+
+ /* icon */
+ if (ale->type == ANIMTYPE_NLACURVE)
+ icon = ICON_NLA;
+ }
uiItemL(col, name, icon);
/* RNA-Path Editing - only really should be enabled when things aren't working */
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index a5c04ce2cb4..87e7cab4d15 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -481,7 +481,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d
ChannelDriver *driver;
float samplefreq;
float stime, etime;
- float unitFac;
+ float unitFac, offset;
float dx, dy;
short mapping_flag = ANIM_get_normalization_flags(ac);
int i, n;
@@ -498,7 +498,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d
fcu->driver = NULL;
/* compute unit correction factor */
- unitFac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag);
+ unitFac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
/* Note about sampling frequency:
* Ideally, this is chosen such that we have 1-2 pixels = 1 segment
@@ -550,7 +550,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d
n = (etime - stime) / samplefreq + 0.5f;
for (i = 0; i <= n; i++) {
float ctime = stime + i * samplefreq;
- glVertex2f(ctime, evaluate_fcurve(fcu, ctime) * unitFac);
+ glVertex2f(ctime, (evaluate_fcurve(fcu, ctime) + offset) * unitFac);
}
glEnd();
@@ -566,13 +566,14 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie
FPoint *fpt = prevfpt + 1;
float fac, v[2];
int b = fcu->totvert - 1;
- float unit_scale;
+ float unit_scale, offset;
short mapping_flag = ANIM_get_normalization_flags(ac);
/* apply unit mapping */
glPushMatrix();
- unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag);
+ unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
glScalef(1.0f, unit_scale, 1.0f);
+ glTranslatef(0.0f, offset, 0.0f);
glBegin(GL_LINE_STRIP);
@@ -665,14 +666,15 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2
float fac = 0.0f;
int b = fcu->totvert - 1;
int resol;
- float unit_scale;
+ float unit_scale, offset;
short mapping_flag = ANIM_get_normalization_flags(ac);
/* apply unit mapping */
glPushMatrix();
- unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag);
+ unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
glScalef(1.0f, unit_scale, 1.0f);
-
+ glTranslatef(0.0f, offset, 0.0f);
+
glBegin(GL_LINE_STRIP);
/* extrapolate to left? */
@@ -826,7 +828,8 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
ChannelDriver *driver = fcu->driver;
View2D *v2d = &ac->ar->v2d;
short mapping_flag = ANIM_get_normalization_flags(ac);
- float unitfac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag);
+ float offset;
+ float unitfac = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag, &offset);
/* for now, only show when debugging driver... */
//if ((driver->flag & DRIVER_FLAG_SHOWDEBUG) == 0)
@@ -850,10 +853,10 @@ static void graph_draw_driver_debug(bAnimContext *ac, ID *id, FCurve *fcu)
glBegin(GL_LINES);
{
t = v2d->cur.xmin;
- glVertex2f(t, t * unitfac);
+ glVertex2f(t, (t + offset) * unitfac);
t = v2d->cur.xmax;
- glVertex2f(t, t * unitfac);
+ glVertex2f(t, (t + offset) * unitfac);
}
glEnd();
@@ -1067,10 +1070,12 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid
}
else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) {
short mapping_flag = ANIM_get_normalization_flags(ac);
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag);
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
glPushMatrix();
glScalef(1.0f, unit_scale, 1.0f);
+ glTranslatef(0.0f, offset, 0.0f);
if (fcu->bezt) {
bool do_handles = draw_fcurve_handles_check(sipo, fcu);
@@ -1137,6 +1142,8 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
/* loop through channels, and set up drawing depending on their type */
{ /* first pass: just the standard GL-drawing for backdrop + text */
+ size_t channel_index = 0;
+
y = (float)ACHANNEL_FIRST;
for (ale = anim_data.first, i = 0; ale; ale = ale->next, i++) {
@@ -1148,11 +1155,12 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar)
IN_RANGE(ymaxc, v2d->cur.ymin, v2d->cur.ymax) )
{
/* draw all channels using standard channel-drawing API */
- ANIM_channel_draw(ac, ale, yminc, ymaxc);
+ ANIM_channel_draw(ac, ale, yminc, ymaxc, channel_index);
}
/* adjust y-position for next one */
y -= ACHANNEL_STEP;
+ channel_index++;
}
}
{ /* second pass: widgets */
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 2944901663b..3de3ecebc44 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -109,7 +109,7 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
FCurve *fcu = (FCurve *)ale->key_data;
float txmin, txmax, tymin, tymax;
- float unitFac;
+ float unitFac, offset;
/* get range */
if (calc_fcurve_bounds(fcu, &txmin, &txmax, &tymin, &tymax, do_sel_only, include_handles)) {
@@ -122,7 +122,9 @@ void get_graph_keyframe_extents(bAnimContext *ac, float *xmin, float *xmax, floa
}
/* apply unit corrections */
- unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag);
+ unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
+ tymin += offset;
+ tymax += offset;
tymin *= unitFac;
tymax *= unitFac;
@@ -256,6 +258,14 @@ static int graphkeys_view_selected_exec(bContext *C, wmOperator *op)
return graphkeys_viewall(C, true, include_handles, smooth_viewtx);
}
+static int graphkeys_view_frame_exec(bContext *C, wmOperator *op)
+{
+ const int smooth_viewtx = WM_operator_smooth_viewtx_get(op);
+ ANIM_center_frame(C, smooth_viewtx);
+ return OPERATOR_FINISHED;
+}
+
+
void GRAPH_OT_view_all(wmOperatorType *ot)
{
/* identifiers */
@@ -294,6 +304,21 @@ void GRAPH_OT_view_selected(wmOperatorType *ot)
"Include handles of keyframes when calculating extents");
}
+void GRAPH_OT_view_frame(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "View Frame";
+ ot->idname = "GRAPH_OT_view_frame";
+ ot->description = "Reset viewable area to show range around current frame";
+
+ /* api callbacks */
+ ot->exec = graphkeys_view_frame_exec;
+ ot->poll = ED_operator_graphedit_active; /* XXX: unchecked poll to get fsamples working too, but makes modifier damage trickier... */
+
+ /* flags */
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+}
+
/* ******************** Create Ghost-Curves Operator *********************** */
/* This operator samples the data of the selected F-Curves to F-Points, storing them
* as 'ghost curves' in the active Graph Editor
@@ -327,7 +352,7 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end)
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
ChannelDriver *driver = fcu->driver;
FPoint *fpt;
- float unitFac;
+ float unitFac, offset;
int cfra;
SpaceIpo *sipo = (SpaceIpo *) ac->sl;
short mapping_flag = ANIM_get_normalization_flags(ac);
@@ -336,7 +361,7 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end)
fcu->driver = NULL;
/* calculate unit-mapping factor */
- unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag);
+ unitFac = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
/* create samples, but store them in a new curve
* - we cannot use fcurve_store_samples() as that will only overwrite the original curve
@@ -349,7 +374,7 @@ static void create_ghost_curves(bAnimContext *ac, int start, int end)
float cfrae = BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
fpt->vec[0] = cfrae;
- fpt->vec[1] = fcurve_samplingcb_evalcurve(fcu, NULL, cfrae) * unitFac;
+ fpt->vec[1] = (fcurve_samplingcb_evalcurve(fcu, NULL, cfrae) + offset) * unitFac;
}
/* set color of ghost curve
@@ -498,12 +523,17 @@ static void insert_graph_keys(bAnimContext *ac, short mode)
else
cfra = (float)CFRA;
- /* if there's an id */
- if (ale->id)
+ /* read value from property the F-Curve represents, or from the curve only?
+ * - ale->id != NULL: Typically, this means that we have enough info to try resolving the path
+ * - ale->owner != NULL: If this is set, then the path may not be resolvable from the ID alone,
+ * so it's easier for now to just read the F-Curve directly.
+ * (TODO: add the full-blown PointerRNA relative parsing case here...)
+ */
+ if (ale->id && !ale->owner)
insert_keyframe(reports, ale->id, NULL, ((fcu->grp) ? (fcu->grp->name) : (NULL)), fcu->rna_path, fcu->array_index, cfra, flag);
else
insert_vert_fcurve(fcu, cfra, fcu->curval, 0);
-
+
ale->update |= ANIM_UPDATE_DEFAULT;
}
@@ -582,7 +612,7 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op)
ListBase anim_data;
short mapping_flag = ANIM_get_normalization_flags(&ac);
-
+ float scale, offset;
/* get frame and value from props */
frame = RNA_float_get(op->ptr, "frame");
val = RNA_float_get(op->ptr, "value");
@@ -592,16 +622,18 @@ static int graphkeys_click_insert_exec(bContext *C, wmOperator *op)
frame = BKE_nla_tweakedit_remap(adt, frame, NLATIME_CONVERT_UNMAP);
/* apply inverse unit-mapping to value to get correct value for F-Curves */
- val *= ANIM_unit_mapping_get_factor(ac.scene, ale->id, fcu, mapping_flag | ANIM_UNITCONV_RESTORE);
-
+ scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, fcu, mapping_flag | ANIM_UNITCONV_RESTORE, &offset);
+
+ val = val * scale - offset;
+
/* insert keyframe on the specified frame + value */
insert_vert_fcurve(fcu, frame, val, 0);
-
+
ale->update |= ANIM_UPDATE_DEPS;
-
+
BLI_listbase_clear(&anim_data);
BLI_addtail(&anim_data, ale);
-
+
ANIM_animdata_update(&ac, &anim_data);
}
else {
@@ -851,13 +883,6 @@ static int graphkeys_duplicate_exec(bContext *C, wmOperator *UNUSED(op))
return OPERATOR_FINISHED;
}
-static int graphkeys_duplicate_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
-{
- graphkeys_duplicate_exec(C, op);
-
- return OPERATOR_FINISHED;
-}
-
void GRAPH_OT_duplicate(wmOperatorType *ot)
{
/* identifiers */
@@ -866,7 +891,6 @@ void GRAPH_OT_duplicate(wmOperatorType *ot)
ot->description = "Make a copy of all selected keyframes";
/* api callbacks */
- ot->invoke = graphkeys_duplicate_invoke;
ot->exec = graphkeys_duplicate_exec;
ot->poll = graphop_editable_keyframes_poll;
@@ -1155,6 +1179,11 @@ static int graphkeys_sound_bake_exec(bContext *C, wmOperator *op)
RNA_string_get(op->ptr, "filepath", path);
+ if (!BLI_is_file(path)) {
+ BKE_reportf(op->reports, RPT_ERROR, "File not found '%s'", path);
+ return OPERATOR_CANCELLED;
+ }
+
scene = ac.scene; /* current scene */
/* store necessary data for the baking steps */
@@ -1877,7 +1906,8 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
AnimData *adt = ANIM_nla_mapping_get(&ac, ale);
short mapping_flag = ANIM_get_normalization_flags(&ac);
KeyframeEditData current_ked;
- float unit_scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS);
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(ac.scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS, &offset);
memset(&current_ked, 0, sizeof(current_ked));
@@ -1891,7 +1921,7 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op))
ked.f1 += current_ked.f1;
ked.i1 += current_ked.i1;
- ked.f2 += current_ked.f2 * unit_scale;
+ ked.f2 += (current_ked.f2 + offset) * unit_scale;
ked.i2 += current_ked.i2;
}
@@ -1984,9 +2014,10 @@ static void snap_graph_keys(bAnimContext *ac, short mode)
/* normalise cursor value (for normalised F-Curves display) */
if (mode == GRAPHKEYS_SNAP_VALUE) {
short mapping_flag = ANIM_get_normalization_flags(ac);
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag);
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag, &offset);
- ked.f1 = cursor_value / unit_scale;
+ ked.f1 = (cursor_value / unit_scale) - offset;
}
/* perform snapping */
@@ -2111,9 +2142,10 @@ static void mirror_graph_keys(bAnimContext *ac, short mode)
/* apply unit corrections */
if (mode == GRAPHKEYS_MIRROR_VALUE) {
short mapping_flag = ANIM_get_normalization_flags(ac);
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS);
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, ale->key_data, mapping_flag | ANIM_UNITCONV_ONLYKEYS, &offset);
- ked.f1 = cursor_value * unit_scale;
+ ked.f1 = (cursor_value + offset) * unit_scale;
}
/* perform actual mirroring */
@@ -2243,7 +2275,7 @@ static EnumPropertyItem *graph_fmodifier_itemf(bContext *C, PointerRNA *UNUSED(p
/* start from 1 to skip the 'Invalid' modifier type */
for (i = 1; i < FMODIFIER_NUM_TYPES; i++) {
- FModifierTypeInfo *fmi = get_fmodifier_typeinfo(i);
+ const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(i);
int index;
/* check if modifier is valid for this context */
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index 50412952139..a478a86a5e2 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -32,11 +32,8 @@
#define __GRAPH_INTERN_H__
struct bContext;
-struct wmWindowManager;
struct bAnimContext;
struct bAnimListElem;
-struct FCurve;
-struct FModifier;
struct SpaceIpo;
struct ScrArea;
struct ARegion;
@@ -94,6 +91,7 @@ void get_graph_keyframe_extents(struct bAnimContext *ac, float *xmin, float *xma
void GRAPH_OT_previewrange_set(struct wmOperatorType *ot);
void GRAPH_OT_view_all(struct wmOperatorType *ot);
void GRAPH_OT_view_selected(struct wmOperatorType *ot);
+void GRAPH_OT_view_frame(struct wmOperatorType *ot);
void GRAPH_OT_click_insert(struct wmOperatorType *ot);
void GRAPH_OT_keyframe_insert(struct wmOperatorType *ot);
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index da308d0b1f1..f4cce29bda8 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -87,8 +87,9 @@ static void graphview_cursor_apply(bContext *C, wmOperator *op)
* NOTE: sync this part of the code with ANIM_OT_change_frame
*/
CFRA = RNA_int_get(op->ptr, "frame");
+ FRAMENUMBER_MIN_CLAMP(CFRA);
SUBFRA = 0.f;
- sound_seek_scene(bmain, scene);
+ BKE_sound_seek_scene(bmain, scene);
/* set the cursor value */
sipo->cursorVal = RNA_float_get(op->ptr, "value");
@@ -380,6 +381,7 @@ void graphedit_operatortypes(void)
WM_operatortype_append(GRAPH_OT_view_all);
WM_operatortype_append(GRAPH_OT_view_selected);
WM_operatortype_append(GRAPH_OT_properties);
+ WM_operatortype_append(GRAPH_OT_view_frame);
WM_operatortype_append(GRAPH_OT_ghost_curves_create);
WM_operatortype_append(GRAPH_OT_ghost_curves_clear);
@@ -440,6 +442,7 @@ void ED_operatormacros_graph(void)
WM_operatortype_macro_define(ot, "GRAPH_OT_duplicate");
otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_transform");
RNA_enum_set(otmacro->ptr, "mode", TFM_TIME_DUPLICATE);
+ RNA_enum_set(otmacro->ptr, "proportional", PROP_EDIT_OFF);
}
@@ -562,15 +565,14 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
WM_keymap_add_item(keymap, "GRAPH_OT_easing_type", EKEY, KM_PRESS, KM_CTRL, 0);
/* destructive */
- WM_keymap_add_item(keymap, "GRAPH_OT_clean", OKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_smooth", OKEY, KM_PRESS, KM_ALT, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_sample", OKEY, KM_PRESS, KM_SHIFT, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_bake", CKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "GRAPH_OT_delete", XKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "GRAPH_OT_delete", DELKEY, KM_PRESS, 0, 0);
-
+ WM_keymap_add_menu(keymap, "GRAPH_MT_delete", XKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_menu(keymap, "GRAPH_MT_delete", DELKEY, KM_PRESS, 0, 0);
+
WM_keymap_add_item(keymap, "GRAPH_OT_duplicate_move", DKEY, KM_PRESS, KM_SHIFT, 0);
/* insertkey */
@@ -594,7 +596,8 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
WM_keymap_add_item(keymap, "GRAPH_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_view_all", NDOF_BUTTON_FIT, KM_PRESS, 0, 0);
WM_keymap_add_item(keymap, "GRAPH_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
-
+ WM_keymap_add_item(keymap, "GRAPH_OT_view_frame", PAD0, KM_PRESS, 0, 0);
+
/* F-Modifiers */
kmi = WM_keymap_add_item(keymap, "GRAPH_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "only_active", false);
@@ -608,6 +611,9 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap)
/* transform system */
transform_keymap_for_space(keyconf, keymap, SPACE_IPO);
+ kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", OKEY, KM_PRESS, 0, 0);
+ RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_proportional_fcurve");
+
/* pivot point settings */
kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0);
RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point");
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 78dbae7618b..4cf8a1de7ab 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -272,7 +272,8 @@ static void borderselect_graphkeys(
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
FCurve *fcu = (FCurve *)ale->key_data;
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag);
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
/* apply NLA mapping to all the keyframes, since it's easier than trying to
* guess when a callback might use something different
@@ -282,8 +283,8 @@ static void borderselect_graphkeys(
scaled_rectf.xmin = rectf.xmin;
scaled_rectf.xmax = rectf.xmax;
- scaled_rectf.ymin = rectf.ymin / unit_scale;
- scaled_rectf.ymax = rectf.ymax / unit_scale;
+ scaled_rectf.ymin = rectf.ymin / unit_scale - offset;
+ scaled_rectf.ymax = rectf.ymax / unit_scale - offset;
/* set horizontal range (if applicable)
* NOTE: these values are only used for x-range and y-range but not region
@@ -1089,6 +1090,8 @@ typedef struct tNearestVertInfo {
short hpoint; /* the handle index that we hit (eHandleIndex) */
short sel; /* whether the handle is selected or not */
int dist; /* distance from mouse to vert */
+
+ eAnim_ChannelType ctype; /* type of animation channel this FCurve comes from */
} tNearestVertInfo;
/* Tags for the type of graph vert that we have */
@@ -1116,8 +1119,8 @@ static bool fcurve_handle_sel_check(SpaceIpo *sipo, BezTriple *bezt)
/* check if the given vertex is within bounds or not */
// TODO: should we return if we hit something?
static void nearest_fcurve_vert_store(
- ListBase *matches, View2D *v2d, FCurve *fcu,
- BezTriple *bezt, FPoint *fpt, short hpoint, const int mval[2], float unit_scale)
+ ListBase *matches, View2D *v2d, FCurve *fcu, eAnim_ChannelType ctype,
+ BezTriple *bezt, FPoint *fpt, short hpoint, const int mval[2], float unit_scale, float offset)
{
/* Keyframes or Samples? */
if (bezt) {
@@ -1129,7 +1132,7 @@ static void nearest_fcurve_vert_store(
* 'vec' matrix
*/
if (UI_view2d_view_to_region_clip(v2d,
- bezt->vec[hpoint + 1][0], bezt->vec[hpoint + 1][1] * unit_scale,
+ bezt->vec[hpoint + 1][0], (bezt->vec[hpoint + 1][1] + offset) * unit_scale,
&screen_co[0], &screen_co[1]) &&
/* check if distance from mouse cursor to vert in screen space is within tolerance */
((dist = len_v2v2_int(mval, screen_co)) <= GVERTSEL_TOL))
@@ -1149,6 +1152,8 @@ static void nearest_fcurve_vert_store(
/* store values */
nvi->fcu = fcu;
+ nvi->ctype = ctype;
+
nvi->bezt = bezt;
nvi->hpoint = hpoint;
nvi->dist = dist;
@@ -1189,30 +1194,31 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag);
-
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
+
/* apply NLA mapping to all the keyframes */
if (adt)
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
-
+
if (fcu->bezt) {
BezTriple *bezt1 = fcu->bezt, *prevbezt = NULL;
int i;
for (i = 0; i < fcu->totvert; i++, prevbezt = bezt1, bezt1++) {
/* keyframe */
- nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_KEY, mval, unit_scale);
+ nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_KEY, mval, unit_scale, offset);
/* handles - only do them if they're visible */
if (fcurve_handle_sel_check(sipo, bezt1) && (fcu->totvert > 1)) {
/* first handle only visible if previous segment had handles */
if ((!prevbezt && (bezt1->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
- nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_LEFT, mval, unit_scale);
+ nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_LEFT, mval, unit_scale, offset);
}
/* second handle only visible if this segment is bezier */
if (bezt1->ipo == BEZT_IPO_BEZ) {
- nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_RIGHT, mval, unit_scale);
+ nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_RIGHT, mval, unit_scale, offset);
}
}
}
@@ -1405,7 +1411,7 @@ static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_m
/* needs to be called with (sipo->flag & SIPO_SELCUVERTSONLY) otherwise the active flag won't be set [#26452] */
if (nvi->fcu->flag & FCURVE_SELECTED) {
int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, ANIMTYPE_FCURVE);
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, nvi->ctype);
}
/* free temp sample data for filtering */
diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c
index eea360ced45..0e56dc817e4 100644
--- a/source/blender/editors/space_graph/graph_utils.c
+++ b/source/blender/editors/space_graph/graph_utils.c
@@ -210,13 +210,18 @@ int graphop_active_fcurve_poll(bContext *C)
if (ale == NULL)
return 0;
- /* free temp data... */
- has_fcurve = ((ale->data) && (ale->type == ANIMTYPE_FCURVE));
+ /* do we have a suitable F-Curves?
+ * - For most cases, NLA Control Curves are sufficiently similar to NLA curves to serve this role too.
+ * Under the hood, they are F-Curves too. The only problems which will arise here are if these need to be
+ * in an Action too (but drivers would then also be affected!)
+ */
+ has_fcurve = ((ale->data) && ELEM(ale->type, ANIMTYPE_FCURVE, ANIMTYPE_NLACURVE));
if (has_fcurve) {
FCurve *fcu = (FCurve *)ale->data;
has_fcurve = (fcu->flag & FCURVE_VISIBLE) != 0;
}
+ /* free temp data... */
MEM_freeN(ale);
/* return success */