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:
authorJoshua Leung <aligorith@gmail.com>2009-07-11 09:41:21 +0400
committerJoshua Leung <aligorith@gmail.com>2009-07-11 09:41:21 +0400
commit4a0df3ad7bd185bbc0ec5a6a42ed1d6b51de8a19 (patch)
tree0fbcae90bbccfb5c65d5e10fb1aca7e5a44c2bea /source/blender/editors/space_graph
parentb80b581bc03b6df28bd3a10118d85b78d5ca011b (diff)
parent576a642ff9b5ca5094f5bb84ada3c5639ae01a92 (diff)
2.5 - NLA SoC Branch Merged to 2.5!
(19863 to 21513) Highlights of the new NLA System (and related Animation System changes): * NLA Data is stored in AnimData alongside Action and Drivers. The NLA stack is evaluated before the Action, with the Action always overriding the results of the stack. * NLA Data is arranged in 'Tracks', which act like PhotoShop layers. These can be muted, protected, and/or made to be played back by themselves * Within each track, there can be multiple 'Strips'. There are 3 types of strip -> Action Clip (references some action), Transition (blends between the endpoints of two strips), and Meta (container for several strips that occur sequentially) * FModifiers can be applied to strips, and strips can have animated influence/time controls. Playback for strips can also be backwards now! * Playback can now go in forward and backwards directions. * Animation Editors have been polished (unfinished features added, existing features cleaned up and made more consistent) Notes for BuildSystem Maintainers: * Only scons has been actively tested. Makefiles should work fine. * MSVC ProjectFiles are broken due to the very way they work. * CMake status unknown... Other notes: * Hopefully I haven't made any mistakes while doing the merge. More files than expected were showing some weird conflicts, so you may have some broken code... * Not all old files (with NLA) data load exactly the same anymore. However, the bulk of the files out there should be ok (I hope)
Diffstat (limited to 'source/blender/editors/space_graph')
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c665
-rw-r--r--source/blender/editors/space_graph/graph_draw.c23
-rw-r--r--source/blender/editors/space_graph/graph_edit.c388
-rw-r--r--source/blender/editors/space_graph/graph_header.c231
-rw-r--r--source/blender/editors/space_graph/graph_intern.h62
-rw-r--r--source/blender/editors/space_graph/graph_ops.c146
-rw-r--r--source/blender/editors/space_graph/graph_select.c87
-rw-r--r--source/blender/editors/space_graph/graph_utils.c288
-rw-r--r--source/blender/editors/space_graph/space_graph.c24
9 files changed, 937 insertions, 977 deletions
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index a4babaad74c..0e48d56ac90 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -347,6 +347,7 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
}
/* ******************* f-modifiers ******************************** */
+/* all the drawing code is in editors/animation/fmodifier_ui.c */
#define B_FMODIFIER_REDRAW 20
@@ -360,671 +361,41 @@ static void do_graph_region_modifier_buttons(bContext *C, void *arg, int event)
}
}
-/* macro for use here to draw background box and set height */
-// XXX for now, roundbox has it's callback func set to NULL to not intercept events
-#define DRAW_BACKDROP(height) \
- { \
- uiDefBut(block, ROUNDBOX, B_REDR, "", -3, *yco-height, width+3, height-1, NULL, 5.0, 0.0, 12.0, (float)rb_col, ""); \
- }
-
-/* callback to verify modifier data */
-static void validate_fmodifier_cb (bContext *C, void *fcu_v, void *fcm_v)
-{
- FModifier *fcm= (FModifier *)fcm_v;
- FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
-
- /* call the verify callback on the modifier if applicable */
- if (fmi && fmi->verify_data)
- fmi->verify_data(fcm);
-}
-
-/* callback to set the active modifier */
-static void activate_fmodifier_cb (bContext *C, void *fcu_v, void *fcm_v)
-{
- FCurve *fcu= (FCurve *)fcu_v;
- FModifier *fcm= (FModifier *)fcm_v;
-
- /* call API function to set the active modifier for active F-Curve */
- fcurve_set_active_modifier(fcu, fcm);
-}
-
-/* callback to remove the given modifier */
-static void delete_fmodifier_cb (bContext *C, void *fcu_v, void *fcm_v)
-{
- FCurve *fcu= (FCurve *)fcu_v;
- FModifier *fcm= (FModifier *)fcm_v;
-
- /* remove the given F-Modifier from the F-Curve */
- fcurve_remove_modifier(fcu, fcm);
-}
-
-/* --------------- */
-
-/* draw settings for generator modifier */
-static void draw_modifier__generator(uiBlock *block, FCurve *fcu, FModifier *fcm, int *yco, short *height, short width, short active, int rb_col)
-{
- FMod_Generator *data= (FMod_Generator *)fcm->data;
- char gen_mode[]="Generator Type%t|Expanded Polynomial%x0|Factorised Polynomial%x1|Built-In Function%x2|Expression%x3";
- char fn_type[]="Built-In Function%t|Sin%x0|Cos%x1|Tan%x2|Square Root%x3|Natural Log%x4";
- int cy= *yco - 30;
- uiBut *but;
-
- /* set the height */
- (*height) = 90;
- switch (data->mode) {
- case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
- (*height) += 20*(data->poly_order+1) + 20;
- break;
- case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* factorised polynomial */
- (*height) += 20 * data->poly_order + 15;
- break;
- case FCM_GENERATOR_FUNCTION: /* builtin function */
- (*height) += 55; // xxx
- break;
- case FCM_GENERATOR_EXPRESSION: /* py-expression */
- // xxx nothing to draw
- break;
- }
-
- /* basic settings (backdrop + mode selector + some padding) */
- DRAW_BACKDROP((*height));
- uiBlockBeginAlign(block);
- but= uiDefButS(block, MENU, B_FMODIFIER_REDRAW, gen_mode, 10,cy,width-30,19, &data->mode, 0, 0, 0, 0, "Selects type of generator algorithm.");
- uiButSetFunc(but, validate_fmodifier_cb, fcu, fcm);
- cy -= 20;
-
- uiDefButBitS(block, TOG, FCM_GENERATOR_ADDITIVE, B_FMODIFIER_REDRAW, "Additive", 10,cy,width-30,19, &data->flag, 0, 0, 0, 0, "Values generated by this modifier are applied on top of the existing values instead of overwriting them");
- cy -= 35;
- uiBlockEndAlign(block);
-
- /* now add settings for individual modes */
- switch (data->mode) {
- case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
- {
- float *cp = NULL;
- char xval[32];
- unsigned int i;
-
- /* draw polynomial order selector */
- but= uiDefButS(block, NUM, B_FMODIFIER_REDRAW, "Poly Order: ", 10,cy,width-30,19, &data->poly_order, 1, 100, 0, 0, "'Order' of the Polynomial - for a polynomial with n terms, 'order' is n-1");
- uiButSetFunc(but, validate_fmodifier_cb, fcu, fcm);
- cy -= 35;
-
- /* draw controls for each coefficient and a + sign at end of row */
- uiDefBut(block, LABEL, 1, "y = ", 0, cy, 50, 20, NULL, 0.0, 0.0, 0, 0, "");
-
- cp= data->coefficients;
- for (i=0; (i < data->arraysize) && (cp); i++, cp++) {
- /* coefficient */
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 50, cy, 150, 20, cp, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, "Coefficient for polynomial");
-
- /* 'x' param (and '+' if necessary) */
- if (i == 0)
- strcpy(xval, "");
- else if (i == 1)
- strcpy(xval, "x");
- else
- sprintf(xval, "x^%d", i);
- uiDefBut(block, LABEL, 1, xval, 200, cy, 50, 20, NULL, 0.0, 0.0, 0, 0, "Power of x");
-
- if ( (i != (data->arraysize - 1)) || ((i==0) && data->arraysize==2) )
- uiDefBut(block, LABEL, 1, "+", 250, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
-
- cy -= 20;
- }
- }
- break;
-
- case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* factorised polynomial expression */
- {
- float *cp = NULL;
- unsigned int i;
-
- /* draw polynomial order selector */
- but= uiDefButS(block, NUM, B_FMODIFIER_REDRAW, "Poly Order: ", 10,cy,width-30,19, &data->poly_order, 1, 100, 0, 0, "'Order' of the Polynomial - for a polynomial with n terms, 'order' is n-1");
- uiButSetFunc(but, validate_fmodifier_cb, fcu, fcm);
- cy -= 35;
-
- /* draw controls for each pair of coefficients */
- uiDefBut(block, LABEL, 1, "y = ", 0, cy, 50, 20, NULL, 0.0, 0.0, 0, 0, "");
-
- cp= data->coefficients;
- for (i=0; (i < data->poly_order) && (cp); i++, cp+=2) {
- /* opening bracket */
- uiDefBut(block, LABEL, 1, "(", 40, cy, 50, 20, NULL, 0.0, 0.0, 0, 0, "");
-
- /* coefficients */
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 50, cy, 100, 20, cp, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, "Coefficient of x");
-
- uiDefBut(block, LABEL, 1, "x + ", 150, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 180, cy, 100, 20, cp+1, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, "Second coefficient");
-
- /* closing bracket and '+' sign */
- if ( (i != (data->poly_order - 1)) || ((i==0) && data->poly_order==2) )
- uiDefBut(block, LABEL, 1, ") â—Š", 280, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
- else
- uiDefBut(block, LABEL, 1, ")", 280, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
-
- cy -= 20;
- }
- }
- break;
-
- case FCM_GENERATOR_FUNCTION: /* built-in function */
- {
- float *cp= data->coefficients;
-
- /* draw function selector */
- but= uiDefButS(block, MENU, B_FMODIFIER_REDRAW, fn_type, 10,cy,width-30,19, &data->func_type, 0, 0, 0, 0, "Built-In Function to use");
- uiButSetFunc(but, validate_fmodifier_cb, fcu, fcm);
- cy -= 35;
-
- /* draw controls for equation of coefficients */
- /* row 1 */
- {
- uiDefBut(block, LABEL, 1, "y = ", 0, cy, 50, 20, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 50, cy, 150, 20, cp+3, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, "Coefficient (D) for function");
- uiDefBut(block, LABEL, 1, "+", 200, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
- cy -= 20;
- }
-
- /* row 2 */
- {
- char func_name[32];
-
- /* coefficient outside bracket */
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 5, cy, 80, 20, cp, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, "Coefficient (A) for function");
-
- /* opening bracket */
- switch (data->func_type)
- {
- case FCM_GENERATOR_FN_SIN: /* sine wave */
- sprintf(func_name, "sin(");
- break;
- case FCM_GENERATOR_FN_COS: /* cosine wave */
- sprintf(func_name, "cos(");
- break;
- case FCM_GENERATOR_FN_TAN: /* tangent wave */
- sprintf(func_name, "tan(");
- break;
- case FCM_GENERATOR_FN_LN: /* natural log */
- sprintf(func_name, "ln(");
- break;
- case FCM_GENERATOR_FN_SQRT: /* square root */
- sprintf(func_name, "sqrt(");
- break;
- default: /* unknown */
- sprintf(func_name, "<fn?>(");
- break;
- }
- uiDefBut(block, LABEL, 1, func_name, 85, cy, 40, 20, NULL, 0.0, 0.0, 0, 0, "");
-
- /* coefficients inside bracket */
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 120, cy, 75, 20, cp+1, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, "Coefficient (B) of x");
-
- uiDefBut(block, LABEL, 1, "x+", 195, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
-
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 225, cy, 80, 20, cp+2, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, "Coefficient (C) of function");
-
- /* closing bracket */
- uiDefBut(block, LABEL, 1, ")", 300, cy, 30, 20, NULL, 0.0, 0.0, 0, 0, "");
- cy -= 20;
- }
- }
- break;
-
- case FCM_GENERATOR_EXPRESSION: /* py-expression */
- // TODO...
- break;
- }
-}
-
-/* --------------- */
-
-/* draw settings for cycles modifier */
-static void draw_modifier__cycles(uiBlock *block, FCurve *fcu, FModifier *fcm, int *yco, short *height, short width, short active, int rb_col)
-{
- FMod_Cycles *data= (FMod_Cycles *)fcm->data;
- char cyc_mode[]="Cycling Mode%t|No Cycles%x0|Repeat Motion%x1|Repeat with Offset%x2|Repeat Mirrored%x3";
- int cy= (*yco - 30), cy1= (*yco - 50), cy2= (*yco - 70);
-
- /* set the height */
- (*height) = 80;
-
- /* basic settings (backdrop + some padding) */
- DRAW_BACKDROP((*height));
-
- /* 'before' range */
- uiDefBut(block, LABEL, 1, "Before:", 4, cy, 80, 20, NULL, 0.0, 0.0, 0, 0, "Settings for cycling before first keyframe");
- uiBlockBeginAlign(block);
- uiDefButS(block, MENU, B_FMODIFIER_REDRAW, cyc_mode, 3,cy1,150,20, &data->before_mode, 0, 0, 0, 0, "Cycling mode to use before first keyframe");
- uiDefButS(block, NUM, B_FMODIFIER_REDRAW, "Max Cycles:", 3, cy2, 150, 20, &data->before_cycles, 0, 10000, 10, 3, "Maximum number of cycles to allow (0 = infinite)");
- uiBlockEndAlign(block);
-
- /* 'after' range */
- uiDefBut(block, LABEL, 1, "After:", 155, cy, 80, 20, NULL, 0.0, 0.0, 0, 0, "Settings for cycling after last keyframe");
- uiBlockBeginAlign(block);
- uiDefButS(block, MENU, B_FMODIFIER_REDRAW, cyc_mode, 157,cy1,150,20, &data->after_mode, 0, 0, 0, 0, "Cycling mode to use after first keyframe");
- uiDefButS(block, NUM, B_FMODIFIER_REDRAW, "Max Cycles:", 157, cy2, 150, 20, &data->after_cycles, 0, 10000, 10, 3, "Maximum number of cycles to allow (0 = infinite)");
- uiBlockEndAlign(block);
-}
-
-/* --------------- */
-
-/* draw settings for noise modifier */
-static void draw_modifier__noise(uiBlock *block, FCurve *fcu, FModifier *fcm, int *yco, short *height, short width, short active, int rb_col)
-{
- FMod_Noise *data= (FMod_Noise *)fcm->data;
- int cy= (*yco - 30), cy1= (*yco - 50), cy2= (*yco - 70);
- char cyc_mode[]="Modification %t|Replace %x0|Add %x1|Subtract %x2|Multiply %x3";
-
- /* set the height */
- (*height) = 80;
-
- /* basic settings (backdrop + some padding) */
- DRAW_BACKDROP((*height));
-
- uiDefButS(block, MENU, B_FMODIFIER_REDRAW, cyc_mode,
- 3, cy, 150, 20, &data->modification, 0, 0, 0, 0, "Method of modifying the existing F-Curve use before first keyframe");
-
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Size:",
- 3, cy1, 150, 20, &data->size, 0.000001, 10000.0, 0.01, 3, "");
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Strength:",
- 3, cy2, 150, 20, &data->strength, 0.0, 10000.0, 0.01, 3, "");
-
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Phase:",
- 155, cy1, 150, 20, &data->phase, 0.0, 100000.0, 0.1, 3, "");
- uiDefButS(block, NUM, B_FMODIFIER_REDRAW, "Depth:",
- 155, cy2, 150, 20, &data->depth, 0, 128, 1, 3, "");
-
-}
-
-/* --------------- */
-
-#define BINARYSEARCH_FRAMEEQ_THRESH 0.0001
-
-/* Binary search algorithm for finding where to insert Envelope Data Point.
- * Returns the index to insert at (data already at that index will be offset if replace is 0)
- */
-static int binarysearch_fcm_envelopedata_index (FCM_EnvelopeData array[], float frame, int arraylen, short *exists)
-{
- int start=0, end=arraylen;
- int loopbreaker= 0, maxloop= arraylen * 2;
-
- /* initialise exists-flag first */
- *exists= 0;
-
- /* sneaky optimisations (don't go through searching process if...):
- * - keyframe to be added is to be added out of current bounds
- * - keyframe to be added would replace one of the existing ones on bounds
- */
- if ((arraylen <= 0) || (array == NULL)) {
- printf("Warning: binarysearch_fcm_envelopedata_index() encountered invalid array \n");
- return 0;
- }
- else {
- /* check whether to add before/after/on */
- float framenum;
-
- /* 'First' Point (when only one point, this case is used) */
- framenum= array[0].time;
- if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
- *exists = 1;
- return 0;
- }
- else if (frame < framenum)
- return 0;
-
- /* 'Last' Point */
- framenum= array[(arraylen-1)].time;
- if (IS_EQT(frame, framenum, BINARYSEARCH_FRAMEEQ_THRESH)) {
- *exists= 1;
- return (arraylen - 1);
- }
- else if (frame > framenum)
- return arraylen;
- }
-
-
- /* most of the time, this loop is just to find where to put it
- * - 'loopbreaker' is just here to prevent infinite loops
- */
- for (loopbreaker=0; (start <= end) && (loopbreaker < maxloop); loopbreaker++) {
- /* compute and get midpoint */
- int mid = start + ((end - start) / 2); /* we calculate the midpoint this way to avoid int overflows... */
- float midfra= array[mid].time;
-
- /* check if exactly equal to midpoint */
- if (IS_EQT(frame, midfra, BINARYSEARCH_FRAMEEQ_THRESH)) {
- *exists = 1;
- return mid;
- }
-
- /* repeat in upper/lower half */
- if (frame > midfra)
- start= mid + 1;
- else if (frame < midfra)
- end= mid - 1;
- }
-
- /* print error if loop-limit exceeded */
- if (loopbreaker == (maxloop-1)) {
- printf("Error: binarysearch_fcm_envelopedata_index() was taking too long \n");
-
- // include debug info
- printf("\tround = %d: start = %d, end = %d, arraylen = %d \n", loopbreaker, start, end, arraylen);
- }
-
- /* not found, so return where to place it */
- return start;
-}
-
-/* callback to add new envelope data point */
-// TODO: should we have a separate file for things like this?
-static void fmod_envelope_addpoint_cb (bContext *C, void *fcm_dv, void *dummy)
-{
- Scene *scene= CTX_data_scene(C);
- FMod_Envelope *env= (FMod_Envelope *)fcm_dv;
- FCM_EnvelopeData *fedn;
- FCM_EnvelopeData fed;
-
- /* init template data */
- fed.min= -1.0f;
- fed.max= 1.0f;
- fed.time= (float)scene->r.cfra; // XXX make this int for ease of use?
- fed.f1= fed.f2= 0;
-
- /* check that no data exists for the current frame... */
- if (env->data) {
- short exists = -1;
- int i= binarysearch_fcm_envelopedata_index(env->data, (float)(scene->r.cfra), env->totvert, &exists);
-
- /* binarysearch_...() will set exists by default to 0, so if it is non-zero, that means that the point exists already */
- if (exists)
- return;
-
- /* add new */
- fedn= MEM_callocN((env->totvert+1)*sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
-
- /* add the points that should occur before the point to be pasted */
- if (i > 0)
- memcpy(fedn, env->data, i*sizeof(FCM_EnvelopeData));
-
- /* add point to paste at index i */
- *(fedn + i)= fed;
-
- /* add the points that occur after the point to be pasted */
- if (i < env->totvert)
- memcpy(fedn+i+1, env->data+i, (env->totvert-i)*sizeof(FCM_EnvelopeData));
-
- /* replace (+ free) old with new */
- MEM_freeN(env->data);
- env->data= fedn;
-
- env->totvert++;
- }
- else {
- env->data= MEM_callocN(sizeof(FCM_EnvelopeData), "FCM_EnvelopeData");
- *(env->data)= fed;
-
- env->totvert= 1;
- }
-}
-
-/* callback to remove envelope data point */
-// TODO: should we have a separate file for things like this?
-static void fmod_envelope_deletepoint_cb (bContext *C, void *fcm_dv, void *ind_v)
-{
- FMod_Envelope *env= (FMod_Envelope *)fcm_dv;
- FCM_EnvelopeData *fedn;
- int index= GET_INT_FROM_POINTER(ind_v);
-
- /* check that no data exists for the current frame... */
- if (env->totvert > 1) {
- /* allocate a new smaller array */
- fedn= MEM_callocN(sizeof(FCM_EnvelopeData)*(env->totvert-1), "FCM_EnvelopeData");
-
- memcpy(fedn, &env->data, sizeof(FCM_EnvelopeData)*(index));
- memcpy(&fedn[index], &env->data[index+1], sizeof(FCM_EnvelopeData)*(env->totvert-index-1));
-
- /* free old array, and set the new */
- MEM_freeN(env->data);
- env->data= fedn;
- env->totvert--;
- }
- else {
- /* just free array, since the only vert was deleted */
- if (env->data)
- MEM_freeN(env->data);
- env->totvert= 0;
- }
-}
-
-/* draw settings for envelope modifier */
-static void draw_modifier__envelope(uiBlock *block, FCurve *fcu, FModifier *fcm, int *yco, short *height, short width, short active, int rb_col)
-{
- FMod_Envelope *env= (FMod_Envelope *)fcm->data;
- FCM_EnvelopeData *fed;
- uiBut *but;
- int cy= (*yco - 28);
- int i;
-
- /* set the height:
- * - basic settings + variable height from envelope controls
- */
- (*height) = 115 + (35 * env->totvert);
-
- /* basic settings (backdrop + general settings + some padding) */
- DRAW_BACKDROP((*height));
-
- /* General Settings */
- uiDefBut(block, LABEL, 1, "Envelope:", 10, cy, 100, 20, NULL, 0.0, 0.0, 0, 0, "Settings for cycling before first keyframe");
- cy -= 20;
-
- uiBlockBeginAlign(block);
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Reference Val:", 10, cy, 300, 20, &env->midval, -UI_FLT_MAX, UI_FLT_MAX, 10, 3, "");
- cy -= 20;
-
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Min:", 10, cy, 150, 20, &env->min, -UI_FLT_MAX, env->max, 10, 3, "Minimum value (relative to Reference Value) that is used as the 'normal' minimum value");
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Max:", 160, cy, 150, 20, &env->max, env->min, UI_FLT_MAX, 10, 3, "Maximum value (relative to Reference Value) that is used as the 'normal' maximum value");
- cy -= 35;
- uiBlockEndAlign(block);
-
-
- /* Points header */
- uiDefBut(block, LABEL, 1, "Control Points:", 10, cy, 150, 20, NULL, 0.0, 0.0, 0, 0, "");
-
- but= uiDefBut(block, BUT, B_FMODIFIER_REDRAW, "Add Point", 160,cy,150,19, NULL, 0, 0, 0, 0, "Adds a new control-point to the envelope on the current frame");
- uiButSetFunc(but, fmod_envelope_addpoint_cb, env, NULL);
- cy -= 35;
-
- /* Points List */
- for (i=0, fed=env->data; i < env->totvert; i++, fed++) {
- uiBlockBeginAlign(block);
- but=uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Fra:", 2, cy, 90, 20, &fed->time, -UI_FLT_MAX, UI_FLT_MAX, 10, 1, "Frame that envelope point occurs");
- uiButSetFunc(but, validate_fmodifier_cb, fcu, fcm);
-
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Min:", 92, cy, 100, 20, &fed->min, -UI_FLT_MAX, UI_FLT_MAX, 10, 2, "Minimum bound of envelope at this point");
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "Max:", 192, cy, 100, 20, &fed->max, -UI_FLT_MAX, UI_FLT_MAX, 10, 2, "Maximum bound of envelope at this point");
-
- but= uiDefIconBut(block, BUT, B_FMODIFIER_REDRAW, ICON_X, 292, cy, 18, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Delete envelope control point");
- uiButSetFunc(but, fmod_envelope_deletepoint_cb, env, SET_INT_IN_POINTER(i));
- uiBlockBeginAlign(block);
- cy -= 25;
- }
-}
-
-/* --------------- */
-
-/* draw settings for limits modifier */
-static void draw_modifier__limits(uiBlock *block, FCurve *fcu, FModifier *fcm, int *yco, short *height, short width, short active, int rb_col)
-{
- FMod_Limits *data= (FMod_Limits *)fcm->data;
- const int togButWidth = 50;
- const int textButWidth = ((width/2)-togButWidth);
-
- /* set the height */
- (*height) = 60;
-
- /* basic settings (backdrop + some padding) */
- DRAW_BACKDROP((*height));
-
- /* Draw Pairs of LimitToggle+LimitValue */
- uiBlockBeginAlign(block);
- uiDefButBitI(block, TOGBUT, FCM_LIMIT_XMIN, B_FMODIFIER_REDRAW, "xMin", 5, *yco-30, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum x value");
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 5+togButWidth, *yco-30, (textButWidth-5), 18, &data->rect.xmin, -UI_FLT_MAX, UI_FLT_MAX, 0.1,0.5,"Lowest x value to allow");
- uiBlockEndAlign(block);
-
- uiBlockBeginAlign(block);
- uiDefButBitI(block, TOGBUT, FCM_LIMIT_XMAX, B_FMODIFIER_REDRAW, "XMax", 5+(width-(textButWidth-5)-togButWidth), *yco-30, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum x value");
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 5+(width-textButWidth-5), *yco-30, (textButWidth-5), 18, &data->rect.xmax, -UI_FLT_MAX, UI_FLT_MAX, 0.1,0.5,"Highest x value to allow");
- uiBlockEndAlign(block);
-
- uiBlockBeginAlign(block);
- uiDefButBitI(block, TOGBUT, FCM_LIMIT_YMIN, B_FMODIFIER_REDRAW, "yMin", 5, *yco-52, togButWidth, 18, &data->flag, 0, 24, 0, 0, "Use minimum y value");
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 5+togButWidth, *yco-52, (textButWidth-5), 18, &data->rect.ymin, -UI_FLT_MAX, UI_FLT_MAX, 0.1,0.5,"Lowest y value to allow");
- uiBlockEndAlign(block);
-
- uiBlockBeginAlign(block);
- uiDefButBitI(block, TOGBUT, FCM_LIMIT_YMAX, B_FMODIFIER_REDRAW, "YMax", 5+(width-(textButWidth-5)-togButWidth), *yco-52, 50, 18, &data->flag, 0, 24, 0, 0, "Use maximum y value");
- uiDefButF(block, NUM, B_FMODIFIER_REDRAW, "", 5+(width-textButWidth-5), *yco-52, (textButWidth-5), 18, &data->rect.ymax, -UI_FLT_MAX, UI_FLT_MAX, 0.1,0.5,"Highest y value to allow");
- uiBlockEndAlign(block);
-}
-
-/* --------------- */
-
-static void graph_panel_modifier_draw(uiBlock *block, FCurve *fcu, FModifier *fcm, int *yco)
-{
- FModifierTypeInfo *fmi= fmodifier_get_typeinfo(fcm);
- uiBut *but;
- short active= (fcm->flag & FMODIFIER_FLAG_ACTIVE);
- short width= 314;
- short height = 0;
- int rb_col;
-
- /* draw header */
- {
- uiBlockSetEmboss(block, UI_EMBOSSN);
-
- /* rounded header */
- rb_col= (active)?-20:20;
- but= uiDefBut(block, ROUNDBOX, B_REDR, "", 0, *yco-2, width, 24, NULL, 5.0, 0.0, 15.0, (float)(rb_col-20), "");
-
- /* expand */
- uiDefIconButBitS(block, ICONTOG, FMODIFIER_FLAG_EXPANDED, B_REDR, ICON_TRIA_RIGHT, 5, *yco-1, 20, 20, &fcm->flag, 0.0, 0.0, 0, 0, "Modifier is expanded.");
-
- /* checkbox for 'active' status (for now) */
- but= uiDefIconButBitS(block, ICONTOG, FMODIFIER_FLAG_ACTIVE, B_REDR, ICON_RADIOBUT_OFF, 25, *yco-1, 20, 20, &fcm->flag, 0.0, 0.0, 0, 0, "Modifier is active one.");
- uiButSetFunc(but, activate_fmodifier_cb, fcu, fcm);
-
- /* name */
- if (fmi)
- uiDefBut(block, LABEL, 1, fmi->name, 10+40, *yco, 150, 20, NULL, 0.0, 0.0, 0, 0, "F-Curve Modifier Type. Click to make modifier active one.");
- else
- uiDefBut(block, LABEL, 1, "<Unknown Modifier>", 10+40, *yco, 150, 20, NULL, 0.0, 0.0, 0, 0, "F-Curve Modifier Type. Click to make modifier active one.");
-
- /* 'mute' button */
- uiDefIconButBitS(block, ICONTOG, FMODIFIER_FLAG_MUTED, B_REDR, ICON_MUTE_IPO_OFF, 10+(width-60), *yco-1, 20, 20, &fcm->flag, 0.0, 0.0, 0, 0, "Modifier is temporarily muted (not evaluated).");
-
- /* delete button */
- but= uiDefIconBut(block, BUT, B_REDR, ICON_X, 10+(width-30), *yco, 19, 19, NULL, 0.0, 0.0, 0.0, 0.0, "Delete F-Curve Modifier.");
- uiButSetFunc(but, delete_fmodifier_cb, fcu, fcm);
-
- uiBlockSetEmboss(block, UI_EMBOSS);
- }
-
- /* when modifier is expanded, draw settings */
- if (fcm->flag & FMODIFIER_FLAG_EXPANDED) {
- /* draw settings for individual modifiers */
- switch (fcm->type) {
- case FMODIFIER_TYPE_GENERATOR: /* Generator */
- draw_modifier__generator(block, fcu, fcm, yco, &height, width, active, rb_col);
- break;
-
- case FMODIFIER_TYPE_CYCLES: /* Cycles */
- draw_modifier__cycles(block, fcu, fcm, yco, &height, width, active, rb_col);
- break;
-
- case FMODIFIER_TYPE_ENVELOPE: /* Envelope */
- draw_modifier__envelope(block, fcu, fcm, yco, &height, width, active, rb_col);
- break;
-
- case FMODIFIER_TYPE_LIMITS: /* Limits */
- draw_modifier__limits(block, fcu, fcm, yco, &height, width, active, rb_col);
- break;
-
- case FMODIFIER_TYPE_NOISE: /* Noise */
- draw_modifier__noise(block, fcu, fcm, yco, &height, width, active, rb_col);
- break;
-
- default: /* unknown type */
- height= 96;
- //DRAW_BACKDROP(height); // XXX buggy...
- break;
- }
- }
-
- /* adjust height for new to start */
- (*yco) -= (height + 27);
-}
-
static void graph_panel_modifiers(const bContext *C, Panel *pa)
{
bAnimListElem *ale;
FCurve *fcu;
FModifier *fcm;
+ uiLayout *col, *row;
uiBlock *block;
- int yco= 190;
- if(!graph_panel_context(C, &ale, &fcu))
+ if (!graph_panel_context(C, &ale, &fcu))
return;
- block= uiLayoutFreeBlock(pa->layout);
+ block= uiLayoutGetBlock(pa->layout);
uiBlockSetHandleFunc(block, do_graph_region_modifier_buttons, NULL);
/* 'add modifier' button at top of panel */
- // XXX for now, this will be a operator button which calls a temporary 'add modifier' operator
- uiDefButO(block, BUT, "GRAPHEDIT_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, "Add Modifier", 10, 225, 150, 20, "Adds a new F-Curve Modifier for the active F-Curve");
+ {
+ row= uiLayoutRow(pa->layout, 0);
+ block= uiLayoutGetBlock(row);
+
+ // XXX for now, this will be a operator button which calls a temporary 'add modifier' operator
+ uiDefButO(block, BUT, "GRAPH_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, "Add Modifier", 10, 0, 150, 20, "Adds a new F-Curve Modifier for the active F-Curve");
+ }
/* draw each modifier */
- for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next)
- graph_panel_modifier_draw(block, fcu, fcm, &yco);
+ for (fcm= fcu->modifiers.first; fcm; fcm= fcm->next) {
+ col= uiLayoutColumn(pa->layout, 1);
+
+ ANIM_uiTemplate_fmodifier_draw(col, ale->id, &fcu->modifiers, fcm);
+ }
MEM_freeN(ale);
}
/* ******************* general ******************************** */
-/* Find 'active' F-Curve. It must be editable, since that's the purpose of these buttons (subject to change).
- * We return the 'wrapper' since it contains valuable context info (about hierarchy), which will need to be freed
- * when the caller is done with it.
- */
-// TODO: move this to anim api with another name?
-bAnimListElem *get_active_fcurve_channel (bAnimContext *ac)
-{
- ListBase anim_data = {NULL, NULL};
- int filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ACTIVE | ANIMFILTER_CURVESONLY);
- int items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
-
- /* We take the first F-Curve only, since some other ones may have had 'active' flag set
- * if they were from linked data.
- */
- if (items) {
- bAnimListElem *ale= (bAnimListElem *)anim_data.first;
-
- /* remove first item from list, then free the rest of the list and return the stored one */
- BLI_remlink(&anim_data, ale);
- BLI_freelistN(&anim_data);
-
- return ale;
- }
-
- /* no active F-Curve */
- return NULL;
-}
-
void graph_buttons_register(ARegionType *art)
{
PanelType *pt;
@@ -1066,10 +437,10 @@ static int graph_properties(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_properties(wmOperatorType *ot)
+void GRAPH_OT_properties(wmOperatorType *ot)
{
ot->name= "Properties";
- ot->idname= "GRAPHEDIT_OT_properties";
+ ot->idname= "GRAPH_OT_properties";
ot->exec= graph_properties;
ot->poll= ED_operator_ipo_active; // xxx
diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c
index ddf4105fdf4..8b242794ca3 100644
--- a/source/blender/editors/space_graph/graph_draw.c
+++ b/source/blender/editors/space_graph/graph_draw.c
@@ -835,12 +835,12 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri
*/
for (ale=anim_data.first; ale; ale=ale->next) {
FCurve *fcu= (FCurve *)ale->key_data;
- FModifier *fcm= fcurve_find_active_modifier(fcu);
- //Object *nob= ANIM_nla_mapping_get(ac, ale);
+ FModifier *fcm= find_active_fmodifier(&fcu->modifiers);
+ AnimData *adt= ANIM_nla_mapping_get(ac, ale);
/* map keyframes for drawing if scaled F-Curve */
- //if (nob)
- // ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 0, 0);
+ if (adt)
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
/* draw curve:
* - curve line may be result of one or more destructive modifiers or just the raw data,
@@ -918,8 +918,8 @@ void graph_draw_curves (bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGri
}
/* undo mapping of keyframes for drawing if scaled F-Curve */
- //if (nob)
- // ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 1, 0);
+ if (adt)
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
}
/* free list of curves */
@@ -1206,6 +1206,17 @@ void graph_draw_channel_names(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar)
expand = ICON_TRIA_RIGHT;
}
+ /* for now, 'special' (i.e. in front of name) is used to show visibility status */
+ if (agrp->flag & AGRP_NOTVISIBLE)
+ special= ICON_CHECKBOX_DEHLT;
+ else
+ special= ICON_CHECKBOX_HLT;
+
+ if (agrp->flag & AGRP_MUTED)
+ mute = ICON_MUTE_IPO_ON;
+ else
+ mute = ICON_MUTE_IPO_OFF;
+
if (EDITABLE_AGRP(agrp))
protect = ICON_UNLOCKED;
else
diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c
index 71f2eb2a8de..1837b6d4ecd 100644
--- a/source/blender/editors/space_graph/graph_edit.c
+++ b/source/blender/editors/space_graph/graph_edit.c
@@ -67,11 +67,13 @@
#include "BKE_fcurve.h"
#include "BKE_key.h"
#include "BKE_material.h"
+#include "BKE_nla.h"
#include "BKE_object.h"
#include "BKE_context.h"
#include "BKE_report.h"
#include "BKE_utildefines.h"
+#include "UI_interface.h"
#include "UI_view2d.h"
#include "ED_anim_api.h"
@@ -114,16 +116,16 @@ void get_graph_keyframe_extents (bAnimContext *ac, float *xmin, float *xmax, flo
if (anim_data.first) {
/* go through channels, finding max extents */
for (ale= anim_data.first; ale; ale= ale->next) {
- Object *nob= NULL; //ANIM_nla_mapping_get(ac, ale);
+ AnimData *adt= ANIM_nla_mapping_get(ac, ale);
FCurve *fcu= (FCurve *)ale->key_data;
float txmin, txmax, tymin, tymax;
/* get range and apply necessary scaling before */
calc_fcurve_bounds(fcu, &txmin, &txmax, &tymin, &tymax);
- if (nob) {
- txmin= get_action_frame_inv(nob, txmin);
- txmax= get_action_frame_inv(nob, txmax);
+ if (adt) {
+ txmin= BKE_nla_tweakedit_remap(adt, txmin, NLATIME_CONVERT_MAP);
+ txmax= BKE_nla_tweakedit_remap(adt, txmax, NLATIME_CONVERT_MAP);
}
/* try to set cur using these values, if they're more extreme than previously set values */
@@ -180,15 +182,15 @@ static int graphkeys_previewrange_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_previewrange_set (wmOperatorType *ot)
+void GRAPH_OT_previewrange_set (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Auto-Set Preview Range";
- ot->idname= "GRAPHEDIT_OT_previewrange_set";
+ ot->idname= "GRAPH_OT_previewrange_set";
/* api callbacks */
ot->exec= graphkeys_previewrange_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_visible_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -227,15 +229,15 @@ static int graphkeys_viewall_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_view_all (wmOperatorType *ot)
+void GRAPH_OT_view_all (wmOperatorType *ot)
{
/* identifiers */
ot->name= "View All";
- ot->idname= "GRAPHEDIT_OT_view_all";
+ ot->idname= "GRAPH_OT_view_all";
/* api callbacks */
ot->exec= graphkeys_viewall_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_visible_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -271,6 +273,7 @@ static void create_ghost_curves (bAnimContext *ac, int start, int end)
for (ale= anim_data.first; ale; ale= ale->next) {
FCurve *fcu= (FCurve *)ale->key_data;
FCurve *gcu= MEM_callocN(sizeof(FCurve), "Ghost FCurve");
+ AnimData *adt= ANIM_nla_mapping_get(ac, ale);
ChannelDriver *driver= fcu->driver;
FPoint *fpt;
int cfra;
@@ -286,8 +289,10 @@ static void create_ghost_curves (bAnimContext *ac, int start, int end)
/* use the sampling callback at 1-frame intervals from start to end frames */
for (cfra= start; cfra <= end; cfra++, fpt++) {
- fpt->vec[0]= (float)cfra;
- fpt->vec[1]= fcurve_samplingcb_evalcurve(fcu, NULL, (float)cfra);
+ float cfrae= BKE_nla_tweakedit_remap(adt, cfra, NLATIME_CONVERT_UNMAP);
+
+ fpt->vec[0]= cfrae;
+ fpt->vec[1]= fcurve_samplingcb_evalcurve(fcu, NULL, cfrae);
}
/* set color of ghost curve
@@ -334,16 +339,16 @@ static int graphkeys_create_ghostcurves_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_ghost_curves_create (wmOperatorType *ot)
+void GRAPH_OT_ghost_curves_create (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Create Ghost Curves";
- ot->idname= "GRAPHEDIT_OT_ghost_curves_create";
+ ot->idname= "GRAPH_OT_ghost_curves_create";
ot->description= "Create snapshot (Ghosts) of selected F-Curves as background aid for active Graph Editor.";
/* api callbacks */
ot->exec= graphkeys_create_ghostcurves_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_visible_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -377,16 +382,16 @@ static int graphkeys_clear_ghostcurves_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_ghost_curves_clear (wmOperatorType *ot)
+void GRAPH_OT_ghost_curves_clear (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Create Ghost Curves";
- ot->idname= "GRAPHEDIT_OT_ghost_curves_clear";
+ ot->idname= "GRAPH_OT_ghost_curves_clear";
ot->description= "Clear F-Curve snapshots (Ghosts) for active Graph Editor.";
/* api callbacks */
ot->exec= graphkeys_clear_ghostcurves_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= ED_operator_ipo_active;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -395,7 +400,103 @@ void GRAPHEDIT_OT_ghost_curves_clear (wmOperatorType *ot)
/* ************************************************************************** */
/* GENERAL STUFF */
-// TODO: insertkey
+/* ******************** Insert Keyframes Operator ************************* */
+
+/* defines for insert keyframes tool */
+EnumPropertyItem prop_graphkeys_insertkey_types[] = {
+ {1, "ALL", 0, "All Channels", ""},
+ {2, "SEL", 0, "Only Selected Channels", ""},
+ {0, NULL, 0, NULL, NULL}
+};
+
+/* this function is responsible for snapping keyframes to frame-times */
+static void insert_graph_keys(bAnimContext *ac, short mode)
+{
+ ListBase anim_data = {NULL, NULL};
+ bAnimListElem *ale;
+ int filter;
+
+ Scene *scene= ac->scene;
+ float cfra= (float)CFRA;
+ short flag = 0;
+
+ /* filter data */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ if (mode == 2) filter |= ANIMFILTER_SEL;
+
+ ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* init keyframing flag */
+ if (IS_AUTOKEY_FLAG(AUTOMATKEY)) flag |= INSERTKEY_MATRIX;
+ if (IS_AUTOKEY_FLAG(INSERTNEEDED)) flag |= INSERTKEY_NEEDED;
+ // if (IS_AUTOKEY_MODE(EDITKEYS)) flag |= INSERTKEY_REPLACE;
+
+ /* insert keyframes */
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ AnimData *adt= ANIM_nla_mapping_get(ac, ale);
+ FCurve *fcu= (FCurve *)ale->key_data;
+
+ /* adjust current frame for NLA-mapping */
+ if (adt)
+ cfra= BKE_nla_tweakedit_remap(adt, (float)CFRA, NLATIME_CONVERT_UNMAP);
+ else
+ cfra= (float)CFRA;
+
+ /* if there's an id */
+ if (ale->id)
+ insert_keyframe(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);
+ }
+
+ BLI_freelistN(&anim_data);
+}
+
+/* ------------------- */
+
+static int graphkeys_insertkey_exec(bContext *C, wmOperator *op)
+{
+ bAnimContext ac;
+ short mode;
+
+ /* get editor data */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return OPERATOR_CANCELLED;
+ if (ac.datatype == ANIMCONT_GPENCIL)
+ return OPERATOR_CANCELLED;
+
+ /* which channels to affect? */
+ mode= RNA_enum_get(op->ptr, "type");
+
+ /* insert keyframes */
+ insert_graph_keys(&ac, mode);
+
+ /* validate keyframes after editing */
+ ANIM_editkeyframes_refresh(&ac);
+
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
+
+ return OPERATOR_FINISHED;
+}
+
+void GRAPH_OT_insert_keyframe (wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name= "Insert Keyframes";
+ ot->idname= "GRAPH_OT_insert_keyframe";
+
+ /* api callbacks */
+ ot->invoke= WM_menu_invoke;
+ ot->exec= graphkeys_insertkey_exec;
+ ot->poll= graphop_editable_keyframes_poll;
+
+ /* flags */
+ ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
+
+ /* id-props */
+ RNA_def_enum(ot->srna, "type", prop_graphkeys_insertkey_types, 0, "Type", "");
+}
/* ******************** Click-Insert Keyframes Operator ************************* */
@@ -403,6 +504,7 @@ static int graphkeys_click_insert_exec (bContext *C, wmOperator *op)
{
bAnimContext ac;
bAnimListElem *ale;
+ AnimData *adt;
float frame, val;
/* get animation context */
@@ -420,14 +522,18 @@ static int graphkeys_click_insert_exec (bContext *C, wmOperator *op)
frame= RNA_float_get(op->ptr, "frame");
val= RNA_float_get(op->ptr, "value");
+ /* apply inverse NLA-mapping to frame to get correct time in un-scaled action */
+ adt= ANIM_nla_mapping_get(&ac, ale);
+ frame= BKE_nla_tweakedit_remap(adt, frame, NLATIME_CONVERT_UNMAP);
+
/* insert keyframe on the specified frame + value */
insert_vert_fcurve((FCurve *)ale->data, frame, val, 0);
/* free temp data */
MEM_freeN(ale);
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
/* done */
return OPERATOR_FINISHED;
@@ -461,16 +567,16 @@ static int graphkeys_click_insert_invoke (bContext *C, wmOperator *op, wmEvent *
return graphkeys_click_insert_exec(C, op);
}
-void GRAPHEDIT_OT_keyframes_click_insert (wmOperatorType *ot)
+void GRAPH_OT_click_insert (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Click-Insert Keyframes";
- ot->idname= "GRAPHEDIT_OT_keyframes_click_insert";
+ ot->idname= "GRAPH_OT_click_insert";
/* api callbacks */
ot->invoke= graphkeys_click_insert_invoke;
ot->exec= graphkeys_click_insert_exec;
- ot->poll= ED_operator_areaactive; // XXX active + editable poll
+ ot->poll= graphop_active_fcurve_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -538,21 +644,19 @@ static int graphkeys_copy_exec(bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
-
+ /* just return - no operator needed here (no changes) */
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_copy (wmOperatorType *ot)
+void GRAPH_OT_copy (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Copy Keyframes";
- ot->idname= "GRAPHEDIT_OT_keyframes_copy";
+ ot->idname= "GRAPH_OT_copy";
/* api callbacks */
ot->exec= graphkeys_copy_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -577,21 +681,21 @@ static int graphkeys_paste_exec(bContext *C, wmOperator *op)
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_paste (wmOperatorType *ot)
+void GRAPH_OT_paste (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Paste Keyframes";
- ot->idname= "GRAPHEDIT_OT_keyframes_paste";
+ ot->idname= "GRAPH_OT_paste";
/* api callbacks */
ot->exec= graphkeys_paste_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -634,8 +738,8 @@ static int graphkeys_duplicate_exec(bContext *C, wmOperator *op)
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
return OPERATOR_FINISHED;
}
@@ -650,16 +754,16 @@ static int graphkeys_duplicate_invoke(bContext *C, wmOperator *op, wmEvent *even
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_duplicate (wmOperatorType *ot)
+void GRAPH_OT_duplicate (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Duplicate Keyframes";
- ot->idname= "GRAPHEDIT_OT_keyframes_duplicate";
+ ot->idname= "GRAPH_OT_duplicate";
/* api callbacks */
ot->invoke= graphkeys_duplicate_invoke;
ot->exec= graphkeys_duplicate_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -705,22 +809,22 @@ static int graphkeys_delete_exec(bContext *C, wmOperator *op)
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_delete (wmOperatorType *ot)
+void GRAPH_OT_delete (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Delete Keyframes";
- ot->idname= "GRAPHEDIT_OT_keyframes_delete";
+ ot->idname= "GRAPH_OT_delete";
/* api callbacks */
ot->invoke= WM_operator_confirm;
ot->exec= graphkeys_delete_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -766,22 +870,22 @@ static int graphkeys_clean_exec(bContext *C, wmOperator *op)
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_clean (wmOperatorType *ot)
+void GRAPH_OT_clean (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Clean Keyframes";
- ot->idname= "GRAPHEDIT_OT_keyframes_clean";
+ ot->idname= "GRAPH_OT_clean";
/* api callbacks */
//ot->invoke= // XXX we need that number popup for this!
ot->exec= graphkeys_clean_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -847,22 +951,23 @@ static int graphkeys_bake_exec(bContext *C, wmOperator *op)
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+ /* set notifier that keyframes have changed */
+ // NOTE: some distinction between order/number of keyframes and type should be made?
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_bake (wmOperatorType *ot)
+void GRAPH_OT_bake (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Bake Curve";
- ot->idname= "GRAPHEDIT_OT_keyframes_bake";
+ ot->idname= "GRAPH_OT_bake";
/* api callbacks */
ot->invoke= WM_operator_confirm; // FIXME...
ot->exec= graphkeys_bake_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -973,21 +1078,21 @@ static int graphkeys_sample_exec(bContext *C, wmOperator *op)
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_sample (wmOperatorType *ot)
+void GRAPH_OT_sample (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Sample Keyframes";
- ot->idname= "GRAPHEDIT_OT_keyframes_sample";
+ ot->idname= "GRAPH_OT_sample";
/* api callbacks */
ot->exec= graphkeys_sample_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1047,22 +1152,22 @@ static int graphkeys_expo_exec(bContext *C, wmOperator *op)
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+ /* set notifier that keyframe properties have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_extrapolation_type (wmOperatorType *ot)
+void GRAPH_OT_extrapolation_type (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Keyframe Extrapolation";
- ot->idname= "GRAPHEDIT_OT_keyframes_extrapolation_type";
+ ot->idname= "GRAPH_OT_extrapolation_type";
/* api callbacks */
ot->invoke= WM_menu_invoke;
ot->exec= graphkeys_expo_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1115,22 +1220,22 @@ static int graphkeys_ipo_exec(bContext *C, wmOperator *op)
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+ /* set notifier that keyframe properties have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_interpolation_type (wmOperatorType *ot)
+void GRAPH_OT_interpolation_type (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Keyframe Interpolation";
- ot->idname= "GRAPHEDIT_OT_keyframes_interpolation_type";
+ ot->idname= "GRAPH_OT_interpolation_type";
/* api callbacks */
ot->invoke= WM_menu_invoke;
ot->exec= graphkeys_ipo_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1203,21 +1308,21 @@ static int graphkeys_handletype_exec(bContext *C, wmOperator *op)
ANIM_editkeyframes_refresh(&ac);
/* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_PROP, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_handletype (wmOperatorType *ot)
+void GRAPH_OT_handletype (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Set Keyframe Handle Type";
- ot->idname= "GRAPHEDIT_OT_keyframes_handletype";
+ ot->idname= "GRAPH_OT_handletype";
/* api callbacks */
ot->invoke= WM_menu_invoke;
ot->exec= graphkeys_handletype_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1298,15 +1403,15 @@ static int graphkeys_euler_filter_exec (bContext *C, wmOperator *op)
return OPERATOR_CANCELLED;
}
-void GRAPHEDIT_OT_keyframes_euler_filter (wmOperatorType *ot)
+void GRAPH_OT_euler_filter (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Euler Filter";
- ot->idname= "GRAPHEDIT_OT_keyframes_euler_filter";
+ ot->idname= "GRAPH_OT_euler_filter";
/* api callbacks */
ot->exec= graphkeys_euler_filter_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1314,10 +1419,10 @@ void GRAPHEDIT_OT_keyframes_euler_filter (wmOperatorType *ot)
#endif // XXX this is not ready for the primetime yet
-/* ***************** Snap Current Frame Operator *********************** */
+/* ***************** Jump to Selected Frames Operator *********************** */
/* snap current-frame indicator to 'average time' of selected keyframe */
-static int graphkeys_cfrasnap_exec(bContext *C, wmOperator *op)
+static int graphkeys_framejump_exec(bContext *C, wmOperator *op)
{
bAnimContext ac;
ListBase anim_data= {NULL, NULL};
@@ -1333,11 +1438,21 @@ static int graphkeys_cfrasnap_exec(bContext *C, wmOperator *op)
memset(&bed, 0, sizeof(BeztEditData));
/* loop over action data, averaging values */
- filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE| ANIMFILTER_CURVESONLY);
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
- for (ale= anim_data.first; ale; ale= ale->next)
- ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, bezt_calc_average, NULL);
+ for (ale= anim_data.first; ale; ale= ale->next) {
+ AnimData *adt= ANIM_nla_mapping_get(&ac, ale);
+
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+ ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, bezt_calc_average, NULL);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
+ }
+ else
+ ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, bezt_calc_average, NULL);
+
+ }
BLI_freelistN(&anim_data);
@@ -1353,15 +1468,15 @@ static int graphkeys_cfrasnap_exec(bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_cfrasnap (wmOperatorType *ot)
+void GRAPH_OT_frame_jump (wmOperatorType *ot)
{
/* identifiers */
- ot->name= "Snap Current Frame to Keys";
- ot->idname= "GRAPHEDIT_OT_keyframes_cfrasnap";
+ ot->name= "Jump to Frame";
+ ot->idname= "GRAPH_OT_frame_jump";
/* api callbacks */
- ot->exec= graphkeys_cfrasnap_exec;
- ot->poll= ED_operator_areaactive;
+ ot->exec= graphkeys_framejump_exec;
+ ot->poll= graphop_visible_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1405,12 +1520,12 @@ static void snap_graph_keys(bAnimContext *ac, short mode)
/* snap keyframes */
for (ale= anim_data.first; ale; ale= ale->next) {
- Object *nob= ANIM_nla_mapping_get(ac, ale);
+ AnimData *adt= ANIM_nla_mapping_get(ac, ale);
- if (nob) {
- ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 0, 1);
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_fcurve);
- ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 1, 1);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
}
else
ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_fcurve);
@@ -1438,22 +1553,22 @@ static int graphkeys_snap_exec(bContext *C, wmOperator *op)
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_snap (wmOperatorType *ot)
+void GRAPH_OT_snap (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Snap Keys";
- ot->idname= "GRAPHEDIT_OT_keyframes_snap";
+ ot->idname= "GRAPH_OT_snap";
/* api callbacks */
ot->invoke= WM_menu_invoke;
ot->exec= graphkeys_snap_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1466,10 +1581,10 @@ void GRAPHEDIT_OT_keyframes_snap (wmOperatorType *ot)
/* defines for mirror keyframes tool */
EnumPropertyItem prop_graphkeys_mirror_types[] = {
- {GRAPHKEYS_MIRROR_CFRA, "CFRA", 0, "Current frame", ""},
- {GRAPHKEYS_MIRROR_YAXIS, "YAXIS", 0, "Vertical Axis", ""},
- {GRAPHKEYS_MIRROR_XAXIS, "XAXIS", 0, "Horizontal Axis", ""},
- {GRAPHKEYS_MIRROR_MARKER, "MARKER", 0, "First Selected Marker", ""},
+ {GRAPHKEYS_MIRROR_CFRA, "CFRA", 0, "By Times over Current frame", ""},
+ {GRAPHKEYS_MIRROR_YAXIS, "YAXIS", 0, "By Times over Time=0", ""},
+ {GRAPHKEYS_MIRROR_XAXIS, "XAXIS", 0, "By Values over Value=0", ""},
+ {GRAPHKEYS_MIRROR_MARKER, "MARKER", 0, "By Times over First Selected Marker", ""},
{0, NULL, 0, NULL, NULL}
};
@@ -1516,12 +1631,12 @@ static void mirror_graph_keys(bAnimContext *ac, short mode)
/* mirror keyframes */
for (ale= anim_data.first; ale; ale= ale->next) {
- Object *nob= ANIM_nla_mapping_get(ac, ale);
+ AnimData *adt= ANIM_nla_mapping_get(ac, ale);
- if (nob) {
- ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 0, 1);
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_fcurve);
- ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 1, 1);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
}
else
ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, NULL, edit_cb, calchandles_fcurve);
@@ -1549,22 +1664,22 @@ static int graphkeys_mirror_exec(bContext *C, wmOperator *op)
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_mirror (wmOperatorType *ot)
+void GRAPH_OT_mirror (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Mirror Keys";
- ot->idname= "GRAPHEDIT_OT_keyframes_mirror";
+ ot->idname= "GRAPH_OT_mirror";
/* api callbacks */
ot->invoke= WM_menu_invoke;
ot->exec= graphkeys_mirror_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1603,21 +1718,21 @@ static int graphkeys_smooth_exec(bContext *C, wmOperator *op)
/* validate keyframes after editing */
ANIM_editkeyframes_refresh(&ac);
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_VALUES);
+ /* set notifier that keyframes have changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_EDIT, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_smooth (wmOperatorType *ot)
+void GRAPH_OT_smooth (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Smooth Keys";
- ot->idname= "GRAPHEDIT_OT_keyframes_smooth";
+ ot->idname= "GRAPH_OT_smooth";
/* api callbacks */
ot->exec= graphkeys_smooth_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_editable_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
@@ -1626,7 +1741,35 @@ void GRAPHEDIT_OT_keyframes_smooth (wmOperatorType *ot)
/* ************************************************************************** */
/* F-CURVE MODIFIERS */
-/* ******************** Add F-Curve Modifier Operator *********************** */
+/* ******************** Add F-Modifier Operator *********************** */
+
+/* present a special customised popup menu for this, with some filtering */
+static int graph_fmodifier_add_invoke (bContext *C, wmOperator *op, wmEvent *event)
+{
+ uiPopupMenu *pup;
+ uiLayout *layout;
+ int i;
+
+ pup= uiPupMenuBegin(C, "Add F-Curve Modifier", 0);
+ layout= uiPupMenuLayout(pup);
+
+ /* start from 1 to skip the 'Invalid' modifier type */
+ for (i = 1; i < FMODIFIER_NUM_TYPES; i++) {
+ FModifierTypeInfo *fmi= get_fmodifier_typeinfo(i);
+
+ /* check if modifier is valid for this context */
+ if (fmi == NULL)
+ continue;
+
+ /* add entry to add this type of modifier */
+ uiItemEnumO(layout, fmi->name, 0, "GRAPH_OT_fmodifier_add", "type", i);
+ }
+ uiItemS(layout);
+
+ uiPupMenuEnd(C, pup);
+
+ return OPERATOR_CANCELLED;
+}
static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
{
@@ -1654,9 +1797,9 @@ static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
type= RNA_enum_get(op->ptr, "type");
/* add F-Modifier of specified type to active F-Curve, and make it the active one */
- fcm= fcurve_add_modifier(fcu, type);
+ fcm= add_fmodifier(&fcu->modifiers, type);
if (fcm)
- fcurve_set_active_modifier(fcu, fcm);
+ set_active_fmodifier(&fcu->modifiers, fcm);
else {
BKE_report(op->reports, RPT_ERROR, "Modifier couldn't be added. See console for details.");
return OPERATOR_CANCELLED;
@@ -1666,21 +1809,22 @@ static int graph_fmodifier_add_exec(bContext *C, wmOperator *op)
ANIM_editkeyframes_refresh(&ac);
/* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_BOTH);
+ // FIXME: this really isn't the best description for it...
+ WM_event_add_notifier(C, NC_ANIMATION, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_fmodifier_add (wmOperatorType *ot)
+void GRAPH_OT_fmodifier_add (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Add F-Curve Modifier";
- ot->idname= "GRAPHEDIT_OT_fmodifier_add";
+ ot->idname= "GRAPH_OT_fmodifier_add";
/* api callbacks */
- ot->invoke= WM_menu_invoke;
+ ot->invoke= graph_fmodifier_add_invoke;
ot->exec= graph_fmodifier_add_exec;
- ot->poll= ED_operator_areaactive; // XXX need active F-Curve
+ ot->poll= graphop_active_fcurve_poll;
/* flags */
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
diff --git a/source/blender/editors/space_graph/graph_header.c b/source/blender/editors/space_graph/graph_header.c
index 178b4b4562f..05d9b2f7e6c 100644
--- a/source/blender/editors/space_graph/graph_header.c
+++ b/source/blender/editors/space_graph/graph_header.c
@@ -43,10 +43,13 @@
#include "BKE_screen.h"
#include "ED_anim_api.h"
+#include "ED_transform.h"
#include "ED_screen.h"
#include "ED_types.h"
#include "ED_util.h"
+#include "RNA_access.h"
+
#include "WM_api.h"
#include "WM_types.h"
@@ -62,77 +65,174 @@
/* ********************************************************* */
/* Menu Defines... */
-/* button events */
-enum {
- B_REDR = 0,
- B_MODECHANGE,
-} eActHeader_ButEvents;
+static void graph_viewmenu(bContext *C, uiLayout *layout, void *arg_unused)
+{
+ bScreen *sc= CTX_wm_screen(C);
+ ScrArea *sa= CTX_wm_area(C);
+ SpaceIpo *sipo= (SpaceIpo*)CTX_wm_space_data(C);
+ PointerRNA spaceptr;
+
+ /* retrieve state */
+ RNA_pointer_create(&sc->id, &RNA_SpaceGraphEditor, sipo, &spaceptr);
+
+ /* create menu */
+ uiItemO(layout, NULL, ICON_MENU_PANEL, "GRAPH_OT_properties");
+
+ uiItemS(layout);
+
+ uiItemR(layout, NULL, 0, &spaceptr, "show_cframe_indicator", 0, 0, 0);
+
+ if (sipo->flag & SIPO_NOHANDLES)
+ uiItemO(layout, "Show Handles", ICON_CHECKBOX_DEHLT, "GRAPH_OT_handles_view_toggle");
+ else
+ uiItemO(layout, "Show Handles", ICON_CHECKBOX_HLT, "GRAPH_OT_handles_view_toggle");
+
+ uiItemR(layout, NULL, 0, &spaceptr, "automerge_keyframes", 0, 0, 0);
+
+ if (sipo->flag & SIPO_DRAWTIME)
+ uiItemO(layout, "Show Frames", 0, "ANIM_OT_time_toggle");
+ else
+ uiItemO(layout, "Show Seconds", 0, "ANIM_OT_time_toggle");
+
+ uiItemS(layout);
+
+ uiItemO(layout, NULL, 0, "ANIM_OT_previewrange_set");
+ uiItemO(layout, NULL, 0, "ANIM_OT_previewrange_clear");
+
+ uiItemO(layout, NULL, 0, "GRAPH_OT_previewrange_set");
+
+ uiItemS(layout);
+
+ uiItemO(layout, NULL, 0, "GRAPH_OT_frame_jump");
+
+ uiItemO(layout, NULL, 0, "GRAPH_OT_view_all");
+
+ if (sa->full)
+ uiItemO(layout, NULL, 0, "SCREEN_OT_screen_full_area"); // "Tile Window", Ctrl UpArrow
+ else
+ uiItemO(layout, NULL, 0, "SCREEN_OT_screen_full_area"); // "Maximize Window", Ctrl DownArrow
+}
-/* ************************ header area region *********************** */
+static void graph_selectmenu(bContext *C, uiLayout *layout, void *arg_unused)
+{
+ uiItemO(layout, NULL, 0, "GRAPH_OT_select_all_toggle");
+ uiItemBooleanO(layout, "Invert All", 0, "GRAPH_OT_select_all_toggle", "invert", 1);
+
+ uiItemS(layout);
+
+ uiItemO(layout, NULL, 0, "GRAPH_OT_select_border");
+ uiItemBooleanO(layout, "Border Axis Range", 0, "GRAPH_OT_select_border", "axis_range", 1);
+
+ uiItemS(layout);
+
+ uiItemEnumO(layout, "Columns on Selected Keys", 0, "GRAPH_OT_select_column", "mode", GRAPHKEYS_COLUMNSEL_KEYS);
+ uiItemEnumO(layout, "Column on Current Frame", 0, "GRAPH_OT_select_column", "mode", GRAPHKEYS_COLUMNSEL_CFRA);
+
+ uiItemEnumO(layout, "Columns on Selected Markers", 0, "GRAPH_OT_select_column", "mode", GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN);
+ uiItemEnumO(layout, "Between Selected Markers", 0, "GRAPH_OT_select_column", "mode", GRAPHKEYS_COLUMNSEL_MARKERS_BETWEEN);
+}
-static void do_viewmenu(bContext *C, void *arg, int event)
+static void graph_channelmenu(bContext *C, uiLayout *layout, void *arg_unused)
{
- SpaceIpo *sipo= (SpaceIpo *)CTX_wm_space_data(C);
+ uiItemO(layout, NULL, 0, "ANIM_OT_channels_setting_toggle");
+ uiItemO(layout, NULL, 0, "ANIM_OT_channels_setting_enable");
+ uiItemO(layout, NULL, 0, "ANIM_OT_channels_setting_disable");
- switch (event) {
- case 1: /* Show time/frames */
- sipo->flag ^= SIPO_DRAWTIME;
- break;
- case 2: /* AutoMerge Keyframes */
- sipo->flag ^= SIPO_NOTRANSKEYCULL;
- break;
- case 3: /* Show/Hide handles */
- sipo->flag ^= SIPO_NOHANDLES;
- break;
- case 4: /* Show current frame number beside indicator */
- sipo->flag ^= SIPO_NODRAWCFRANUM;
- break;
- }
+ uiItemS(layout);
+
+ uiItemO(layout, NULL, 0, "ANIM_OT_channels_editable_toggle");
+
+ uiItemS(layout);
+
+ uiItemO(layout, NULL, 0, "ANIM_OT_channels_expand");
+ uiItemO(layout, NULL, 0, "ANIM_OT_channels_collapse");
}
-static uiBlock *graph_viewmenu(bContext *C, ARegion *ar, void *arg_unused)
+static void graph_edit_transformmenu(bContext *C, uiLayout *layout, void *arg_unused)
{
- ScrArea *curarea= CTX_wm_area(C);
- SpaceIpo *sipo= (SpaceIpo *)CTX_wm_space_data(C);
- uiBlock *block;
- short yco= 0, menuwidth=120;
+ uiItemEnumO(layout, "Grab/Move", 0, "TFM_OT_transform", "mode", TFM_TIME_TRANSLATE);
+ uiItemEnumO(layout, "Extend", 0, "TFM_OT_transform", "mode", TFM_TIME_EXTEND);
+ uiItemEnumO(layout, "Scale", 0, "TFM_OT_transform", "mode", TFM_TIME_SCALE);
+}
+
+static void graph_edit_snapmenu(bContext *C, uiLayout *layout, void *arg_unused)
+{
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_CFRA);
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_NEAREST_FRAME);
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_NEAREST_SECOND);
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_snap", "type", GRAPHKEYS_SNAP_NEAREST_MARKER);
+}
+
+static void graph_edit_mirrormenu(bContext *C, uiLayout *layout, void *arg_unused)
+{
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_mirror", "type", GRAPHKEYS_MIRROR_CFRA);
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_mirror", "type", GRAPHKEYS_MIRROR_YAXIS);
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_mirror", "type", GRAPHKEYS_MIRROR_XAXIS);
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_mirror", "type", GRAPHKEYS_MIRROR_MARKER);
+}
+
+static void graph_edit_handlesmenu(bContext *C, uiLayout *layout, void *arg_unused)
+{
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_handle_type", "type", HD_FREE);
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_handle_type", "type", HD_AUTO);
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_handle_type", "type", HD_VECT);
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_handle_type", "type", HD_ALIGN);
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_handle_type", "type", HD_AUTO_ANIM); // xxx?
+}
+
+static void graph_edit_ipomenu(bContext *C, uiLayout *layout, void *arg_unused)
+{
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_interpolation_type", "type", BEZT_IPO_CONST);
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_interpolation_type", "type", BEZT_IPO_LIN);
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_interpolation_type", "type", BEZT_IPO_BEZ);
+}
+
+static void graph_edit_expomenu(bContext *C, uiLayout *layout, void *arg_unused)
+{
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_extrapolation_type", "type", FCURVE_EXTRAPOLATE_CONSTANT);
+ uiItemEnumO(layout, NULL, 0, "GRAPH_OT_extrapolation_type", "type", FCURVE_EXTRAPOLATE_LINEAR);
+}
+
+static void graph_editmenu(bContext *C, uiLayout *layout, void *arg_unused)
+{
+ uiItemMenuF(layout, "Transform", 0, graph_edit_transformmenu);
+ uiItemMenuF(layout, "Snap", 0, graph_edit_snapmenu);
+ uiItemMenuF(layout, "Mirror", 0, graph_edit_mirrormenu);
- block= uiBeginBlock(C, ar, "graph_viewmenu", UI_EMBOSSP);
- uiBlockSetButmFunc(block, do_viewmenu, NULL);
+ uiItemS(layout);
- // XXX these options should use new menu-options
+ uiItemO(layout, NULL, 0, "GRAPH_OT_insert_keyframe");
+ uiItemO(layout, NULL, 0, "GRAPH_OT_fmodifier_add");
- if (sipo->flag & SIPO_DRAWTIME) {
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Show Frames|Ctrl T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
- }
- else {
- uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
- "Show Seconds|Ctrl T", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
- }
+ uiItemS(layout);
+ uiItemO(layout, NULL, 0, "GRAPH_OT_duplicate");
+ uiItemO(layout, NULL, 0, "GRAPH_OT_delete");
- uiDefIconTextBut(block, BUTM, 1, (sipo->flag & SIPO_NOTRANSKEYCULL)?ICON_CHECKBOX_DEHLT:ICON_CHECKBOX_HLT,
- "AutoMerge Keyframes|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
- uiDefIconTextBut(block, BUTM, 1, (sipo->flag & SIPO_NOHANDLES)?ICON_CHECKBOX_DEHLT:ICON_CHECKBOX_HLT,
- "Show Handles|Ctrl H", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 3, "");
- uiDefIconTextBut(block, BUTM, 1, (sipo->flag & SIPO_NODRAWCFRANUM)?ICON_CHECKBOX_DEHLT:ICON_CHECKBOX_HLT,
- "Show Current Frame Number|", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 1, 4, "");
+ uiItemS(layout);
- if (curarea->headertype==HEADERTOP) {
- uiBlockSetDirection(block, UI_DOWN);
- }
- else {
- uiBlockSetDirection(block, UI_TOP);
- uiBlockFlipOrder(block);
- }
+ uiItemMenuF(layout, "Handle Type", 0, graph_edit_handlesmenu);
+ uiItemMenuF(layout, "Interpolation Mode", 0, graph_edit_ipomenu);
+ uiItemMenuF(layout, "Extrapolation Mode", 0, graph_edit_expomenu);
- uiTextBoundsBlock(block, 50);
- uiEndBlock(C, block);
+ uiItemS(layout);
+
+ uiItemO(layout, NULL, 0, "GRAPH_OT_clean");
+ uiItemO(layout, NULL, 0, "GRAPH_OT_sample");
+
+ uiItemS(layout);
- return block;
+ uiItemO(layout, NULL, 0, "GRAPH_OT_copy");
+ uiItemO(layout, NULL, 0, "GRAPH_OT_paste");
}
+/* ********************************************************* */
+
+enum {
+ B_REDR = 0,
+ B_MODECHANGE,
+} eGraphEdit_Events;
+
static void do_graph_buttons(bContext *C, void *arg, int event)
{
switch (event) {
@@ -163,8 +263,19 @@ void graph_header_buttons(const bContext *C, ARegion *ar)
int xmax;
xmax= GetButStringLength("View");
- uiDefPulldownBut(block, graph_viewmenu, CTX_wm_area(C),
- "View", xco, yco-2, xmax-3, 24, "");
+ uiDefMenuBut(block, graph_viewmenu, NULL, "View", xco, yco, xmax-3, 20, "");
+ xco+= xmax;
+
+ xmax= GetButStringLength("Select");
+ uiDefMenuBut(block, graph_selectmenu, NULL, "Select", xco, yco, xmax-3, 20, "");
+ xco+= xmax;
+
+ xmax= GetButStringLength("Channel");
+ uiDefMenuBut(block, graph_channelmenu, NULL, "Channel", xco, yco, xmax-3, 20, "");
+ xco+= xmax;
+
+ xmax= GetButStringLength("Key");
+ uiDefMenuBut(block, graph_editmenu, NULL, "Key", xco, yco, xmax-3, 20, "");
xco+= xmax;
}
@@ -202,8 +313,8 @@ void graph_header_buttons(const bContext *C, ARegion *ar)
/* copy + paste */
uiBlockBeginAlign(block);
- uiDefIconButO(block, BUT, "GRAPHEDIT_OT_keyframes_copy", WM_OP_INVOKE_REGION_WIN, ICON_COPYDOWN, xco+=XIC,yco,XIC,YIC, "Copies the selected keyframes from the selected channel(s) to the buffer");
- uiDefIconButO(block, BUT, "GRAPHEDIT_OT_keyframes_paste", WM_OP_INVOKE_REGION_WIN, ICON_PASTEDOWN, xco+=XIC,yco,XIC,YIC, "Pastes the keyframes from the buffer");
+ uiDefIconButO(block, BUT, "GRAPH_OT_copy", WM_OP_INVOKE_REGION_WIN, ICON_COPYDOWN, xco+=XIC,yco,XIC,YIC, "Copies the selected keyframes from the selected channel(s) to the buffer");
+ uiDefIconButO(block, BUT, "GRAPH_OT_paste", WM_OP_INVOKE_REGION_WIN, ICON_PASTEDOWN, xco+=XIC,yco,XIC,YIC, "Pastes the keyframes from the buffer");
uiBlockEndAlign(block);
xco += (XIC + 8);
@@ -225,9 +336,9 @@ void graph_header_buttons(const bContext *C, ARegion *ar)
/* ghost curves */
// XXX these icons need to be changed
if (sipo->ghostCurves.first)
- uiDefIconButO(block, BUT, "GRAPHEDIT_OT_ghost_curves_clear", WM_OP_INVOKE_REGION_WIN, ICON_OUTLINER_DATA_CURVE, xco,yco,XIC,YIC, "Clear F-Curve snapshots (Ghosts) for this Graph Editor instance");
+ uiDefIconButO(block, BUT, "GRAPH_OT_ghost_curves_clear", WM_OP_INVOKE_REGION_WIN, ICON_OUTLINER_DATA_CURVE, xco,yco,XIC,YIC, "Clear F-Curve snapshots (Ghosts) for this Graph Editor instance");
else
- uiDefIconButO(block, BUT, "GRAPHEDIT_OT_ghost_curves_create", WM_OP_INVOKE_REGION_WIN, ICON_OUTLINER_OB_CURVE, xco,yco,XIC,YIC, "Create snapshot (Ghosts) of selected F-Curves as background aid for this Graph Editor instance");
+ uiDefIconButO(block, BUT, "GRAPH_OT_ghost_curves_create", WM_OP_INVOKE_REGION_WIN, ICON_OUTLINER_OB_CURVE, xco,yco,XIC,YIC, "Create snapshot (Ghosts) of selected F-Curves as background aid for this Graph Editor instance");
xco+= XIC;
diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h
index e31adf7a7c8..697c31eaa98 100644
--- a/source/blender/editors/space_graph/graph_intern.h
+++ b/source/blender/editors/space_graph/graph_intern.h
@@ -32,6 +32,8 @@ struct bContext;
struct wmWindowManager;
struct bAnimContext;
struct bAnimListElem;
+struct FCurve;
+struct FModifier;
struct SpaceIpo;
struct ScrArea;
struct ARegion;
@@ -58,10 +60,10 @@ void graph_header_buttons(const bContext *C, struct ARegion *ar);
/* ***************************************** */
/* graph_select.c */
-void GRAPHEDIT_OT_keyframes_select_all_toggle(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_select_border(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_columnselect(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_clickselect(struct wmOperatorType *ot);
+void GRAPH_OT_select_all_toggle(struct wmOperatorType *ot);
+void GRAPH_OT_select_border(struct wmOperatorType *ot);
+void GRAPH_OT_select_column(struct wmOperatorType *ot);
+void GRAPH_OT_clickselect(struct wmOperatorType *ot);
/* defines for left-right select tool */
enum {
@@ -84,28 +86,29 @@ enum {
void get_graph_keyframe_extents (struct bAnimContext *ac, float *xmin, float *xmax, float *ymin, float *ymax);
-void GRAPHEDIT_OT_previewrange_set(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_view_all(struct wmOperatorType *ot);
+void GRAPH_OT_previewrange_set(struct wmOperatorType *ot);
+void GRAPH_OT_view_all(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_click_insert(struct wmOperatorType *ot);
+void GRAPH_OT_click_insert(struct wmOperatorType *ot);
+void GRAPH_OT_insert_keyframe(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_copy(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_paste(struct wmOperatorType *ot);
+void GRAPH_OT_copy(struct wmOperatorType *ot);
+void GRAPH_OT_paste(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_duplicate(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_delete(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_clean(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_sample(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_bake(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_smooth(struct wmOperatorType *ot);
+void GRAPH_OT_duplicate(struct wmOperatorType *ot);
+void GRAPH_OT_delete(struct wmOperatorType *ot);
+void GRAPH_OT_clean(struct wmOperatorType *ot);
+void GRAPH_OT_sample(struct wmOperatorType *ot);
+void GRAPH_OT_bake(struct wmOperatorType *ot);
+void GRAPH_OT_smooth(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_handletype(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_interpolation_type(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_extrapolation_type(struct wmOperatorType *ot);
+void GRAPH_OT_handletype(struct wmOperatorType *ot);
+void GRAPH_OT_interpolation_type(struct wmOperatorType *ot);
+void GRAPH_OT_extrapolation_type(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_cfrasnap(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_snap(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_keyframes_mirror(struct wmOperatorType *ot);
+void GRAPH_OT_frame_jump(struct wmOperatorType *ot);
+void GRAPH_OT_snap(struct wmOperatorType *ot);
+void GRAPH_OT_mirror(struct wmOperatorType *ot);
/* defines for snap keyframes
* NOTE: keep in sync with eEditKeyframes_Snap (in ED_keyframes_edit.h)
@@ -130,20 +133,29 @@ enum {
/* ----------- */
-void GRAPHEDIT_OT_fmodifier_add(struct wmOperatorType *ot);
+void GRAPH_OT_fmodifier_add(struct wmOperatorType *ot);
/* ----------- */
-void GRAPHEDIT_OT_ghost_curves_create(struct wmOperatorType *ot);
-void GRAPHEDIT_OT_ghost_curves_clear(struct wmOperatorType *ot);
+void GRAPH_OT_ghost_curves_create(struct wmOperatorType *ot);
+void GRAPH_OT_ghost_curves_clear(struct wmOperatorType *ot);
/* ***************************************** */
/* graph_buttons.c */
-void GRAPHEDIT_OT_properties(struct wmOperatorType *ot);
+void GRAPH_OT_properties(struct wmOperatorType *ot);
void graph_buttons_register(struct ARegionType *art);
+/* ***************************************** */
+/* graph_utils.c */
+
struct bAnimListElem *get_active_fcurve_channel(struct bAnimContext *ac);
+short fcurve_needs_draw_fmodifier_controls(struct FCurve *fcu, struct FModifier *fcm);
+
+int graphop_visible_keyframes_poll(struct bContext *C);
+int graphop_editable_keyframes_poll(struct bContext *C);
+int graphop_active_fcurve_poll(struct bContext *C);
+
/* ***************************************** */
/* graph_ops.c */
void graphedit_keymap(struct wmWindowManager *wm);
diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c
index d1a678f91d4..305ad825030 100644
--- a/source/blender/editors/space_graph/graph_ops.c
+++ b/source/blender/editors/space_graph/graph_ops.c
@@ -57,6 +57,10 @@
#include "WM_api.h"
#include "WM_types.h"
+/* ************************** poll callbacks **********************************/
+
+
+
/* ************************** view-based operators **********************************/
// XXX this probably shouldn't be here..
@@ -79,15 +83,15 @@ static int view_toggle_handles_exec (bContext *C, wmOperator *op)
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_view_togglehandles (wmOperatorType *ot)
+void GRAPH_OT_view_togglehandles (wmOperatorType *ot)
{
/* identification */
ot->name= "Show/Hide All Handles";
- ot->idname= "GRAPHEDIT_OT_handles_view_toggle";
+ ot->idname= "GRAPH_OT_handles_view_toggle";
/* callbacks */
ot->exec= view_toggle_handles_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= ED_operator_ipo_active;
}
/* ************************** registration - operator types **********************************/
@@ -95,45 +99,44 @@ void GRAPHEDIT_OT_view_togglehandles (wmOperatorType *ot)
void graphedit_operatortypes(void)
{
/* view */
- WM_operatortype_append(GRAPHEDIT_OT_view_togglehandles);
- WM_operatortype_append(GRAPHEDIT_OT_previewrange_set);
- WM_operatortype_append(GRAPHEDIT_OT_view_all);
- WM_operatortype_append(GRAPHEDIT_OT_properties);
+ WM_operatortype_append(GRAPH_OT_view_togglehandles);
+ WM_operatortype_append(GRAPH_OT_previewrange_set);
+ WM_operatortype_append(GRAPH_OT_view_all);
+ WM_operatortype_append(GRAPH_OT_properties);
- WM_operatortype_append(GRAPHEDIT_OT_ghost_curves_create);
- WM_operatortype_append(GRAPHEDIT_OT_ghost_curves_clear);
+ WM_operatortype_append(GRAPH_OT_ghost_curves_create);
+ WM_operatortype_append(GRAPH_OT_ghost_curves_clear);
/* keyframes */
/* selection */
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_clickselect);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_select_all_toggle);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_select_border);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_columnselect);
+ WM_operatortype_append(GRAPH_OT_clickselect);
+ WM_operatortype_append(GRAPH_OT_select_all_toggle);
+ WM_operatortype_append(GRAPH_OT_select_border);
+ WM_operatortype_append(GRAPH_OT_select_column);
/* editing */
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_snap);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_mirror);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_cfrasnap);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_handletype);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_interpolation_type);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_extrapolation_type);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_sample);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_bake);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_smooth);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_clean);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_delete);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_duplicate);
-
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_copy);
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_paste);
-
- WM_operatortype_append(GRAPHEDIT_OT_keyframes_click_insert);
-
- //TODO: insertkey...
+ WM_operatortype_append(GRAPH_OT_snap);
+ WM_operatortype_append(GRAPH_OT_mirror);
+ WM_operatortype_append(GRAPH_OT_frame_jump);
+ WM_operatortype_append(GRAPH_OT_handletype);
+ WM_operatortype_append(GRAPH_OT_interpolation_type);
+ WM_operatortype_append(GRAPH_OT_extrapolation_type);
+ WM_operatortype_append(GRAPH_OT_sample);
+ WM_operatortype_append(GRAPH_OT_bake);
+ WM_operatortype_append(GRAPH_OT_smooth);
+ WM_operatortype_append(GRAPH_OT_clean);
+ WM_operatortype_append(GRAPH_OT_delete);
+ WM_operatortype_append(GRAPH_OT_duplicate);
+
+ WM_operatortype_append(GRAPH_OT_copy);
+ WM_operatortype_append(GRAPH_OT_paste);
+
+ WM_operatortype_append(GRAPH_OT_insert_keyframe);
+ WM_operatortype_append(GRAPH_OT_click_insert);
/* F-Curve Modifiers */
// XXX temporary?
- WM_operatortype_append(GRAPHEDIT_OT_fmodifier_add);
+ WM_operatortype_append(GRAPH_OT_fmodifier_add);
}
/* ************************** registration - keymaps **********************************/
@@ -143,81 +146,82 @@ static void graphedit_keymap_keyframes (wmWindowManager *wm, ListBase *keymap)
wmKeymapItem *kmi;
/* view */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_handles_view_toggle", HKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_handles_view_toggle", HKEY, KM_PRESS, KM_CTRL, 0);
/* graph_select.c - selection tools */
/* click-select */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, 0, 0);
- kmi= WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, 0, 0);
+ kmi= WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "column", 1);
- kmi= WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
+ kmi= WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", 1);
- kmi= WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT|KM_SHIFT, 0);
+ kmi= WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_ALT|KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "extend", 1);
RNA_boolean_set(kmi->ptr, "column", 1);
- kmi= WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
+ kmi= WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
RNA_enum_set(kmi->ptr, "left_right", GRAPHKEYS_LRSEL_TEST);
- kmi= WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_ALT, 0);
+ kmi= WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_ALT, 0);
RNA_boolean_set(kmi->ptr, "curves", 1);
- kmi= WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_ALT|KM_SHIFT, 0);
+ kmi= WM_keymap_add_item(keymap, "GRAPH_OT_clickselect", SELECTMOUSE, KM_PRESS, KM_CTRL|KM_ALT|KM_SHIFT, 0);
RNA_boolean_set(kmi->ptr, "curves", 1);
RNA_boolean_set(kmi->ptr, "extend", 1);
/* deselect all */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_select_all_toggle", AKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1);
+ WM_keymap_add_item(keymap, "GRAPH_OT_select_all_toggle", AKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_all_toggle", IKEY, KM_PRESS, KM_CTRL, 0)->ptr, "invert", 1);
/* borderselect */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_select_border", BKEY, KM_PRESS, 0, 0);
- RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_select_border", BKEY, KM_PRESS, KM_ALT, 0)->ptr, "axis_range", 1);
+ WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, 0, 0);
+ RNA_boolean_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_border", BKEY, KM_PRESS, KM_ALT, 0)->ptr, "axis_range", 1);
/* column select */
// XXX KKEY would be nice to keep for 'keyframe' lines
- RNA_enum_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_columnselect", KKEY, KM_PRESS, 0, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_KEYS);
- RNA_enum_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_columnselect", KKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_CFRA);
- RNA_enum_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_columnselect", KKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN);
- RNA_enum_set(WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_columnselect", KKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_MARKERS_BETWEEN);
+ RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, 0, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_KEYS);
+ RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, KM_CTRL, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_CFRA);
+ RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, KM_SHIFT, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN);
+ RNA_enum_set(WM_keymap_add_item(keymap, "GRAPH_OT_select_column", KKEY, KM_PRESS, KM_ALT, 0)->ptr, "mode", GRAPHKEYS_COLUMNSEL_MARKERS_BETWEEN);
/* graph_edit.c */
/* snap - current frame to selected keys */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_cfrasnap", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+ // TODO: maybe since this is called jump, we're better to have it on <something>-J?
+ WM_keymap_add_item(keymap, "GRAPH_OT_frame_jump", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
/* menu + single-step transform */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_mirror", MKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_snap", SKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_mirror", MKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_handletype", HKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_interpolation_type", TKEY, KM_PRESS, KM_SHIFT, 0);
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_extrapolation_type", EKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_handletype", HKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_interpolation_type", TKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_extrapolation_type", EKEY, KM_PRESS, KM_SHIFT, 0);
/* destructive */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_clean", OKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_smooth", OKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_sample", OKEY, KM_PRESS, KM_SHIFT, 0);
+ 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, "GRAPHEDIT_OT_keyframes_bake", CKEY, KM_PRESS, KM_ALT, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_bake", CKEY, KM_PRESS, KM_ALT, 0);
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_delete", XKEY, KM_PRESS, 0, 0);
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_delete", DELKEY, KM_PRESS, 0, 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_item(keymap, "GRAPHEDIT_OT_keyframes_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_duplicate", DKEY, KM_PRESS, KM_SHIFT, 0);
/* insertkey */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_click_insert", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_insert_keyframe", IKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_click_insert", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
/* copy/paste */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_copy", CKEY, KM_PRESS, KM_CTRL, 0);
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_keyframes_paste", VKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_copy", CKEY, KM_PRESS, KM_CTRL, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_paste", VKEY, KM_PRESS, KM_CTRL, 0);
/* auto-set range */
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_previewrange_set", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_previewrange_set", PKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
- /* F-Curve Modifiers */
- // XXX these are temporary? operators...
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
+ /* F-Modifiers */
+ WM_keymap_add_item(keymap, "GRAPH_OT_fmodifier_add", MKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
/* transform system */
@@ -232,7 +236,7 @@ void graphedit_keymap(wmWindowManager *wm)
/* keymap for all regions */
keymap= WM_keymap_listbase(wm, "GraphEdit Generic", SPACE_IPO, 0);
- WM_keymap_add_item(keymap, "GRAPHEDIT_OT_properties", NKEY, KM_PRESS, 0, 0);
+ WM_keymap_add_item(keymap, "GRAPH_OT_properties", NKEY, KM_PRESS, 0, 0);
/* channels */
/* Channels are not directly handled by the Graph Editor module, but are inherited from the Animation module.
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 7746f49d135..a78cacb42ef 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -63,6 +63,7 @@
#include "BKE_fcurve.h"
#include "BKE_key.h"
#include "BKE_material.h"
+#include "BKE_nla.h"
#include "BKE_object.h"
#include "BKE_context.h"
#include "BKE_utildefines.h"
@@ -168,20 +169,20 @@ static int graphkeys_deselectall_exec(bContext *C, wmOperator *op)
deselect_graph_keys(&ac, 1, SELECT_ADD);
/* set notifier that things have changed */
- ED_area_tag_redraw(CTX_wm_area(C)); // FIXME... should be updating 'keyframes' data context or so instead!
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_SELECT, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_select_all_toggle (wmOperatorType *ot)
+void GRAPH_OT_select_all_toggle (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select All";
- ot->idname= "GRAPHEDIT_OT_keyframes_select_all_toggle";
+ ot->idname= "GRAPH_OT_select_all_toggle";
/* api callbacks */
ot->exec= graphkeys_deselectall_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_visible_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
@@ -231,14 +232,14 @@ static void borderselect_graphkeys (bAnimContext *ac, rcti rect, short mode, sho
/* loop over data, doing border select */
for (ale= anim_data.first; ale; ale= ale->next) {
- Object *nob= ANIM_nla_mapping_get(ac, ale);
+ AnimData *adt= ANIM_nla_mapping_get(ac, ale);
/* set horizontal range (if applicable) */
if (mode != BEZT_OK_VALUERANGE) {
/* if channel is mapped in NLA, apply correction */
- if (nob) {
- bed.f1= get_action_frame(nob, rectf.xmin);
- bed.f2= get_action_frame(nob, rectf.xmax);
+ if (adt) {
+ bed.f1= BKE_nla_tweakedit_remap(adt, rectf.xmin, NLATIME_CONVERT_UNMAP);
+ bed.f2= BKE_nla_tweakedit_remap(adt, rectf.xmax, NLATIME_CONVERT_UNMAP);
}
else {
bed.f1= rectf.xmin;
@@ -301,21 +302,24 @@ static int graphkeys_borderselect_exec(bContext *C, wmOperator *op)
/* apply borderselect action */
borderselect_graphkeys(&ac, rect, mode, selectmode);
+ /* send notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_SELECT, NULL);
+
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_select_border(wmOperatorType *ot)
+void GRAPH_OT_select_border(wmOperatorType *ot)
{
/* identifiers */
ot->name= "Border Select";
- ot->idname= "GRAPHEDIT_OT_keyframes_select_border";
+ ot->idname= "GRAPH_OT_select_border";
/* api callbacks */
ot->invoke= WM_border_select_invoke;
ot->exec= graphkeys_borderselect_exec;
ot->modal= WM_border_select_modal;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_visible_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
@@ -379,12 +383,12 @@ static void markers_selectkeys_between (bAnimContext *ac)
/* select keys in-between */
for (ale= anim_data.first; ale; ale= ale->next) {
- Object *nob= ANIM_nla_mapping_get(ac, ale);
+ AnimData *adt= ANIM_nla_mapping_get(ac, ale);
- if (nob) {
- ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 0, 1);
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL);
- ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 1, 1);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
}
else {
ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL);
@@ -450,15 +454,15 @@ static void columnselect_graph_keys (bAnimContext *ac, short mode)
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
- Object *nob= ANIM_nla_mapping_get(ac, ale);
+ AnimData *adt= ANIM_nla_mapping_get(ac, ale);
/* loop over cfraelems (stored in the BeztEditData->list)
* - we need to do this here, as we can apply fewer NLA-mapping conversions
*/
for (ce= bed.list.first; ce; ce= ce->next) {
/* set frame for validation callback to refer to */
- if (nob)
- bed.f1= get_action_frame(nob, ce->cfra);
+ if (ale)
+ bed.f1= BKE_nla_tweakedit_remap(adt, ce->cfra, NLATIME_CONVERT_UNMAP);
else
bed.f1= ce->cfra;
@@ -491,21 +495,21 @@ static int graphkeys_columnselect_exec(bContext *C, wmOperator *op)
else
columnselect_graph_keys(&ac, mode);
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_KEYFRAMES_SELECT);
+ /* set notifier that keyframe selection has changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_SELECT, NULL);
return OPERATOR_FINISHED;
}
-void GRAPHEDIT_OT_keyframes_columnselect (wmOperatorType *ot)
+void GRAPH_OT_select_column (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Select All";
- ot->idname= "GRAPHEDIT_OT_keyframes_columnselect";
+ ot->idname= "GRAPH_OT_select_column";
/* api callbacks */
ot->exec= graphkeys_columnselect_exec;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_visible_keyframes_poll;
/* flags */
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
@@ -566,11 +570,16 @@ static short findnearest_fcurve_vert (bAnimContext *ac, int mval[2], FCurve **fc
for (ale= anim_data.first; ale; ale= ale->next) {
FCurve *fcu= (FCurve *)ale->key_data;
+ AnimData *adt= ANIM_nla_mapping_get(ac, ale);
/* try to progressively get closer to the right point... */
if (fcu->bezt) {
BezTriple *bezt1=fcu->bezt, *prevbezt=NULL;
+ /* apply NLA mapping to all the keyframes */
+ if (adt)
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
+
for (i=0; i < fcu->totvert; i++, prevbezt=bezt1, bezt1++) {
/* convert beztriple points to screen-space */
UI_view2d_to_region_no_clip(v2d, bezt1->vec[0][0], bezt1->vec[0][1], &sco[0][0], &sco[0][1]);
@@ -624,6 +633,10 @@ static short findnearest_fcurve_vert (bAnimContext *ac, int mval[2], FCurve **fc
}
}
}
+
+ /* un-apply NLA mapping from all the keyframes */
+ if (adt)
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
}
}
@@ -722,7 +735,7 @@ static void mouse_graph_keys (bAnimContext *ac, int mval[], short select_mode, s
/* set active F-Curve (NOTE: sync the filter flags with findnearest_fcurve_vert) */
if (fcu->flag & FCURVE_SELECTED) {
filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVEVISIBLE | ANIMFILTER_CURVESONLY);
- ANIM_set_active_channel(ac->data, ac->datatype, filter, fcu, ANIMTYPE_FCURVE);
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, fcu, ANIMTYPE_FCURVE);
}
}
@@ -753,7 +766,7 @@ static void graphkeys_mselect_leftright (bAnimContext *ac, short leftright, shor
memset(&bed, 0, sizeof(BeztEditFunc));
if (leftright == GRAPHKEYS_LRSEL_LEFT) {
- bed.f1 = -MAXFRAMEF;
+ bed.f1 = MINAFRAMEF;
bed.f2 = (float)(CFRA + 0.1f);
}
else {
@@ -767,12 +780,12 @@ static void graphkeys_mselect_leftright (bAnimContext *ac, short leftright, shor
/* select keys on the side where most data occurs */
for (ale= anim_data.first; ale; ale= ale->next) {
- Object *nob= ANIM_nla_mapping_get(ac, ale);
+ AnimData *adt= ANIM_nla_mapping_get(ac, ale);
- if (nob) {
- ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 0, 1);
+ if (adt) {
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL);
- ANIM_nla_mapping_apply_fcurve(nob, ale->key_data, 1, 1);
+ ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
}
else
ANIM_fcurve_keys_bezier_loop(&bed, ale->key_data, ok_cb, select_cb, NULL);
@@ -827,11 +840,11 @@ static void graphkeys_mselect_column (bAnimContext *ac, int mval[2], short selec
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
for (ale= anim_data.first; ale; ale= ale->next) {
- Object *nob= ANIM_nla_mapping_get(ac, ale);
+ AnimData *adt= ANIM_nla_mapping_get(ac, ale);
/* set frame for validation callback to refer to */
- if (nob)
- bed.f1= get_action_frame(nob, selx);
+ if (adt)
+ bed.f1= BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
else
bed.f1= selx;
@@ -901,22 +914,22 @@ static int graphkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *ev
mouse_graph_keys(&ac, mval, selectmode, 0);
}
- /* set notifier that things have changed */
- ANIM_animdata_send_notifiers(C, &ac, ANIM_CHANGED_BOTH);
+ /* set notifier that keyframe selection (and also channel selection in some cases) has changed */
+ WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME_SELECT|ND_ANIMCHAN_SELECT, NULL);
/* for tweak grab to work */
return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
}
-void GRAPHEDIT_OT_keyframes_clickselect (wmOperatorType *ot)
+void GRAPH_OT_clickselect (wmOperatorType *ot)
{
/* identifiers */
ot->name= "Mouse Select Keys";
- ot->idname= "GRAPHEDIT_OT_keyframes_clickselect";
+ ot->idname= "GRAPH_OT_clickselect";
/* api callbacks */
ot->invoke= graphkeys_clickselect_invoke;
- ot->poll= ED_operator_areaactive;
+ ot->poll= graphop_visible_keyframes_poll;
/* id-props */
// XXX should we make this into separate operators?
diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c
new file mode 100644
index 00000000000..f00e7845549
--- /dev/null
+++ b/source/blender/editors/space_graph/graph_utils.c
@@ -0,0 +1,288 @@
+/**
+ * $Id:
+ *
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2009 Blender Foundation.
+ * All rights reserved.
+ *
+ *
+ * Contributor(s): Blender Foundation, Joshua Leung
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+#include <string.h>
+#include <stdio.h>
+#include <math.h>
+#include <float.h>
+
+#include "DNA_anim_types.h"
+#include "DNA_action_types.h"
+#include "DNA_object_types.h"
+#include "DNA_space_types.h"
+#include "DNA_scene_types.h"
+#include "DNA_screen_types.h"
+#include "DNA_userdef_types.h"
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_arithb.h"
+#include "BLI_blenlib.h"
+#include "BLI_editVert.h"
+#include "BLI_rand.h"
+
+#include "BKE_animsys.h"
+#include "BKE_action.h"
+#include "BKE_context.h"
+#include "BKE_curve.h"
+#include "BKE_customdata.h"
+#include "BKE_depsgraph.h"
+#include "BKE_fcurve.h"
+#include "BKE_object.h"
+#include "BKE_global.h"
+#include "BKE_scene.h"
+#include "BKE_screen.h"
+#include "BKE_utildefines.h"
+
+#include "BIF_gl.h"
+
+#include "WM_api.h"
+#include "WM_types.h"
+
+#include "RNA_access.h"
+#include "RNA_define.h"
+
+#include "ED_anim_api.h"
+#include "ED_keyframing.h"
+#include "ED_screen.h"
+#include "ED_types.h"
+#include "ED_util.h"
+
+#include "UI_interface.h"
+#include "UI_resources.h"
+#include "UI_view2d.h"
+
+#include "graph_intern.h" // own include
+
+/* ************************************************************** */
+/* Active F-Curve */
+
+/* Find 'active' F-Curve. It must be editable, since that's the purpose of these buttons (subject to change).
+ * We return the 'wrapper' since it contains valuable context info (about hierarchy), which will need to be freed
+ * when the caller is done with it.
+ */
+bAnimListElem *get_active_fcurve_channel (bAnimContext *ac)
+{
+ ListBase anim_data = {NULL, NULL};
+ int filter= (ANIMFILTER_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ACTIVE | ANIMFILTER_CURVESONLY);
+ int items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* We take the first F-Curve only, since some other ones may have had 'active' flag set
+ * if they were from linked data.
+ */
+ if (items) {
+ bAnimListElem *ale= (bAnimListElem *)anim_data.first;
+
+ /* remove first item from list, then free the rest of the list and return the stored one */
+ BLI_remlink(&anim_data, ale);
+ BLI_freelistN(&anim_data);
+
+ return ale;
+ }
+
+ /* no active F-Curve */
+ return NULL;
+}
+
+/* ************************************************************** */
+/* Operator Polling Callbacks */
+
+/* check if any FModifiers to draw controls for - fcm is 'active' modifier
+ * used for the polling callbacks + also for drawing
+ */
+short fcurve_needs_draw_fmodifier_controls (FCurve *fcu, FModifier *fcm)
+{
+ /* don't draw if there aren't any modifiers at all */
+ if (fcu->modifiers.first == NULL)
+ return 0;
+
+ /* if there's an active modifier - don't draw if it doesn't drastically
+ * alter the curve...
+ */
+ if (fcm) {
+ switch (fcm->type) {
+ /* clearly harmless */
+ case FMODIFIER_TYPE_CYCLES:
+ return 0;
+
+ /* borderline... */
+ case FMODIFIER_TYPE_NOISE:
+ return 0;
+ }
+ }
+
+ /* if only one modifier - don't draw if it is muted or disabled */
+ if (fcu->modifiers.first == fcu->modifiers.last) {
+ fcm= fcu->modifiers.first;
+ if (fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED))
+ return 0;
+ }
+
+ /* if only active modifier - don't draw if it is muted or disabled */
+ if (fcm) {
+ if (fcm->flag & (FMODIFIER_FLAG_DISABLED|FMODIFIER_FLAG_MUTED))
+ return 0;
+ }
+
+ /* if we're still here, this means that there are modifiers with controls to be drawn */
+ // FIXME: what happens if all the modifiers were muted/disabled
+ return 1;
+}
+
+/* ------------------- */
+
+/* Check if there are any visible keyframes (for selection tools) */
+int graphop_visible_keyframes_poll (bContext *C)
+{
+ bAnimContext ac;
+ bAnimListElem *ale;
+ ListBase anim_data = {NULL, NULL};
+ ScrArea *sa= CTX_wm_area(C);
+ int filter, items;
+ short found = 0;
+
+ /* firstly, check if in Graph Editor */
+ // TODO: also check for region?
+ if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
+ return 0;
+
+ /* try to init Anim-Context stuff ourselves and check */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return 0;
+
+ /* loop over the visible (selection doesn't matter) F-Curves, and see if they're suitable
+ * stopping on the first successful match
+ */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CURVESONLY);
+ items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ if (items == 0)
+ return 0;
+
+ for (ale = anim_data.first; ale; ale= ale->next) {
+ FCurve *fcu= (FCurve *)ale->data;
+ FModifier *fcm;
+
+ /* visible curves for selection must fulfull the following criteria:
+ * - it has bezier keyframes
+ * - F-Curve modifiers do not interfere with the result too much
+ * (i.e. the modifier-control drawing check returns false)
+ */
+ if (fcu->bezt == NULL)
+ continue;
+ fcm= find_active_fmodifier(&fcu->modifiers);
+
+ found= (fcurve_needs_draw_fmodifier_controls(fcu, fcm) == 0);
+ if (found) break;
+ }
+
+ /* cleanup and return findings */
+ BLI_freelistN(&anim_data);
+ return found;
+}
+
+/* Check if there are any visible + editable keyframes (for editing tools) */
+int graphop_editable_keyframes_poll (bContext *C)
+{
+ bAnimContext ac;
+ bAnimListElem *ale;
+ ListBase anim_data = {NULL, NULL};
+ ScrArea *sa= CTX_wm_area(C);
+ int filter, items;
+ short found = 0;
+
+ /* firstly, check if in Graph Editor */
+ // TODO: also check for region?
+ if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
+ return 0;
+
+ /* try to init Anim-Context stuff ourselves and check */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return 0;
+
+ /* loop over the editable (selected + editable) F-Curves, and see if they're suitable
+ * stopping on the first successful match
+ */
+ filter= (ANIMFILTER_VISIBLE | ANIMFILTER_SEL | ANIMFILTER_FOREDIT | ANIMFILTER_CURVESONLY);
+ items = ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+ if (items == 0)
+ return 0;
+
+ for (ale = anim_data.first; ale; ale= ale->next) {
+ FCurve *fcu= (FCurve *)ale->data;
+ FModifier *fcm;
+
+ /* editable curves must fulfull the following criteria:
+ * - it has bezier keyframes
+ * - it must not be protected from editing (this is already checked for with the foredit flag
+ * - F-Curve modifiers do not interfere with the result too much
+ * (i.e. the modifier-control drawing check returns false)
+ */
+ if (fcu->bezt == NULL)
+ continue;
+ fcm= find_active_fmodifier(&fcu->modifiers);
+
+ found= (fcurve_needs_draw_fmodifier_controls(fcu, fcm) == 0);
+ if (found) break;
+ }
+
+ /* cleanup and return findings */
+ BLI_freelistN(&anim_data);
+ return found;
+}
+
+/* has active F-Curve that's editable */
+int graphop_active_fcurve_poll (bContext *C)
+{
+ bAnimContext ac;
+ bAnimListElem *ale;
+ ScrArea *sa= CTX_wm_area(C);
+ short has_fcurve= 0;
+
+ /* firstly, check if in Graph Editor */
+ // TODO: also check for region?
+ if ((sa == NULL) || (sa->spacetype != SPACE_IPO))
+ return 0;
+
+ /* try to init Anim-Context stuff ourselves and check */
+ if (ANIM_animdata_get_context(C, &ac) == 0)
+ return 0;
+
+ /* try to get the Active F-Curve */
+ ale= get_active_fcurve_channel(&ac);
+ if (ale == NULL)
+ return 0;
+
+ /* free temp data... */
+ has_fcurve= ((ale->data) && (ale->type == ANIMTYPE_FCURVE));
+ MEM_freeN(ale);
+
+ /* return success */
+ return has_fcurve;
+}
+
+/* ************************************************************** */
diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c
index 1c977724767..a5578e88076 100644
--- a/source/blender/editors/space_graph/space_graph.c
+++ b/source/blender/editors/space_graph/space_graph.c
@@ -72,19 +72,19 @@ ARegion *graph_has_buttons_region(ScrArea *sa)
if(ar->regiontype==RGN_TYPE_UI)
return ar;
- /* add subdiv level; after channel */
+ /* add subdiv level; after main window */
for(ar= sa->regionbase.first; ar; ar= ar->next)
- if(ar->regiontype==RGN_TYPE_CHANNELS)
+ if(ar->regiontype==RGN_TYPE_WINDOW)
break;
/* is error! */
if(ar==NULL) return NULL;
- arnew= MEM_callocN(sizeof(ARegion), "buttons for view3d");
+ arnew= MEM_callocN(sizeof(ARegion), "buttons for nla");
BLI_insertlinkafter(&sa->regionbase, ar, arnew);
arnew->regiontype= RGN_TYPE_UI;
- arnew->alignment= RGN_ALIGN_BOTTOM|RGN_SPLIT_PREV;
+ arnew->alignment= RGN_ALIGN_RIGHT;
arnew->flag = RGN_FLAG_HIDDEN;
@@ -117,7 +117,7 @@ static SpaceLink *graph_new(const bContext *C)
ar->alignment= RGN_ALIGN_BOTTOM;
/* channels */
- ar= MEM_callocN(sizeof(ARegion), "main area for graphedit");
+ ar= MEM_callocN(sizeof(ARegion), "channels area for graphedit");
BLI_addtail(&sipo->regionbase, ar);
ar->regiontype= RGN_TYPE_CHANNELS;
@@ -126,11 +126,11 @@ static SpaceLink *graph_new(const bContext *C)
ar->v2d.scroll = (V2D_SCROLL_RIGHT|V2D_SCROLL_BOTTOM);
/* ui buttons */
- ar= MEM_callocN(sizeof(ARegion), "main area for graphedit");
+ ar= MEM_callocN(sizeof(ARegion), "buttons area for graphedit");
BLI_addtail(&sipo->regionbase, ar);
ar->regiontype= RGN_TYPE_UI;
- ar->alignment= RGN_ALIGN_TOP|RGN_SPLIT_PREV;
+ ar->alignment= RGN_ALIGN_RIGHT;
ar->flag = RGN_FLAG_HIDDEN;
/* main area */
@@ -192,7 +192,7 @@ static SpaceLink *graph_duplicate(SpaceLink *sl)
SpaceIpo *sipon= MEM_dupallocN(sl);
/* clear or remove stuff from old */
- //sipon->ipokey.first= sipon->ipokey.last= NULL;
+ BLI_duplicatelist(&sipon->ghostCurves, &((SpaceIpo *)sl)->ghostCurves);
sipon->ads= MEM_dupallocN(sipon->ads);
return (SpaceLink *)sipon;
@@ -365,6 +365,9 @@ static void graph_region_listener(ARegion *ar, wmNotifier *wmn)
{
/* context changes */
switch(wmn->category) {
+ case NC_ANIMATION:
+ ED_region_tag_redraw(ar);
+ break;
case NC_SCENE:
switch(wmn->data) {
case ND_OB_ACTIVE:
@@ -395,6 +398,9 @@ static void graph_listener(ScrArea *sa, wmNotifier *wmn)
{
/* context changes */
switch (wmn->category) {
+ case NC_ANIMATION:
+ ED_area_tag_refresh(sa);
+ break;
case NC_SCENE:
/*switch (wmn->data) {
case ND_OB_ACTIVE:
@@ -566,7 +572,7 @@ void ED_spacetype_ipo(void)
/* regions: UI buttons */
art= MEM_callocN(sizeof(ARegionType), "spacetype graphedit region");
art->regionid = RGN_TYPE_UI;
- art->minsizey= 200;
+ art->minsizex= 200;
art->keymapflag= ED_KEYMAP_UI;
art->listener= graph_region_listener;
art->init= graph_buttons_area_init;