diff options
Diffstat (limited to 'source/blender/editors/space_graph')
-rw-r--r-- | source/blender/editors/space_graph/graph_buttons.c | 68 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_draw.c | 83 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_edit.c | 4 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_intern.h | 1 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_ops.c | 201 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_select.c | 85 | ||||
-rw-r--r-- | source/blender/editors/space_graph/graph_utils.c | 1 | ||||
-rw-r--r-- | source/blender/editors/space_graph/space_graph.c | 4 |
8 files changed, 384 insertions, 63 deletions
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index b59030d3c12..a2b64afdb15 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -159,7 +159,7 @@ static void graph_panel_properties(const bContext *C, Panel *pa) // UNUSED // block = uiLayoutGetBlock(layout); - // uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); + // UI_block_func_handle_set(block, do_graph_region_buttons, NULL); /* F-Curve pointer */ RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr); @@ -315,7 +315,7 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) return; block = uiLayoutGetBlock(layout); - /* uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL); */ + /* UI_block_func_handle_set(block, do_graph_region_buttons, NULL); */ /* only show this info if there are keyframes to edit */ if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) { @@ -366,33 +366,33 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) { uiItemL(col, IFACE_("Key:"), ICON_NONE); - but = uiDefButR(block, NUM, B_REDR, IFACE_("Frame:"), 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Frame:"), 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "co", 0, 0, 0, -1, -1, NULL); - uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt); + UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt); - but = uiDefButR(block, NUM, B_REDR, IFACE_("Value:"), 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Value:"), 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "co", 1, 0, 0, -1, -1, NULL); - uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt); - uiButSetUnitType(but, unit); + UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt); + UI_but_unit_type_set(but, unit); } /* previous handle - only if previous was Bezier interpolation */ if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) { uiItemL(col, IFACE_("Left Handle:"), ICON_NONE); - but = uiDefButR(block, NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL); - uiButSetFunc(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt); + UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt); - but = uiDefButR(block, NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL); - uiButSetFunc(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt); - uiButSetUnitType(but, unit); + UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt); + UI_but_unit_type_set(but, unit); /* XXX: with label? */ - but = uiDefButR(block, MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_left_type", 0, 0, 0, -1, -1, "Type of left handle"); - uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); + UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt); } /* next handle - only if current is Bezier interpolation */ @@ -400,19 +400,19 @@ static void graph_panel_key_properties(const bContext *C, Panel *pa) /* NOTE: special update callbacks are needed on the coords here due to T39911 */ uiItemL(col, IFACE_("Right Handle:"), ICON_NONE); - but = uiDefButR(block, NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL); - uiButSetFunc(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt); + UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt); - but = uiDefButR(block, NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL); - uiButSetFunc(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt); - uiButSetUnitType(but, unit); + UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt); + UI_but_unit_type_set(but, unit); /* XXX: with label? */ - but = uiDefButR(block, MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y, + but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y, &bezt_ptr, "handle_right_type", 0, 0, 0, -1, -1, "Type of right handle"); - uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt); + UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt); } } else { @@ -671,22 +671,22 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) /* set event handler for panel */ block = uiLayoutGetBlock(pa->layout); // xxx? - uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL); + UI_block_func_handle_set(block, do_graph_region_driver_buttons, NULL); /* general actions - management */ col = uiLayoutColumn(pa->layout, false); block = uiLayoutGetBlock(col); - but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"), + but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"), 0, 0, 10 * UI_UNIT_X, 22, NULL, 0.0, 0.0, 0, 0, TIP_("Force updates of dependencies")); - uiButSetFunc(but, driver_update_flags_cb, fcu, NULL); + UI_but_func_set(but, driver_update_flags_cb, fcu, NULL); - but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_ZOOMOUT, IFACE_("Remove Driver"), + but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMOUT, IFACE_("Remove Driver"), 0, 0, 10 * UI_UNIT_X, 18, NULL, 0.0, 0.0, 0, 0, TIP_("Remove this driver")); - uiButSetNFunc(but, driver_remove_cb, MEM_dupallocN(ale), NULL); + UI_but_funcN_set(but, driver_remove_cb, MEM_dupallocN(ale), NULL); /* driver-level settings - type, expressions, and errors */ RNA_pointer_create(ale->id, &RNA_Driver, driver, &driver_ptr); @@ -763,11 +763,11 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) /* add driver variables */ col = uiLayoutColumn(pa->layout, false); block = uiLayoutGetBlock(col); - but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Variable"), + but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Variable"), 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, TIP_("Driver variables ensure that all dependencies will be accounted for and that drivers will update correctly")); - uiButSetFunc(but, driver_add_var_cb, driver, NULL); + UI_but_func_set(but, driver_add_var_cb, driver, NULL); /* loop over targets, drawing them */ for (dvar = driver->variables.first; dvar; dvar = dvar->next) { @@ -788,11 +788,11 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) uiItemR(row, &dvar_ptr, "name", 0, "", ICON_NONE); /* remove button */ - uiBlockSetEmboss(block, UI_EMBOSSN); - but = uiDefIconBut(block, BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y, + UI_block_emboss_set(block, UI_EMBOSS_NONE); + but = uiDefIconBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Delete target variable")); - uiButSetFunc(but, driver_delete_var_cb, driver, dvar); - uiBlockSetEmboss(block, UI_EMBOSS); + UI_but_func_set(but, driver_delete_var_cb, driver, dvar); + UI_block_emboss_set(block, UI_EMBOSS); /* variable type */ row = uiLayoutRow(box, false); @@ -869,7 +869,7 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa) return; block = uiLayoutGetBlock(pa->layout); - uiBlockSetHandleFunc(block, do_graph_region_modifier_buttons, NULL); + UI_block_func_handle_set(block, do_graph_region_modifier_buttons, NULL); /* 'add modifier' button at top of panel */ { @@ -879,7 +879,7 @@ static void graph_panel_modifiers(const bContext *C, Panel *pa) /* this is an operator button which calls a 'add modifier' operator... * a menu might be nicer but would be tricky as we need some custom filtering */ - uiDefButO(block, BUT, "GRAPH_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"), + uiDefButO(block, UI_BTYPE_BUT, "GRAPH_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"), 0.5 * UI_UNIT_X, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, TIP_("Adds a new F-Curve Modifier for the active F-Curve")); /* copy/paste (as sub-row)*/ diff --git a/source/blender/editors/space_graph/graph_draw.c b/source/blender/editors/space_graph/graph_draw.c index ed7cfe7da99..9093734f25f 100644 --- a/source/blender/editors/space_graph/graph_draw.c +++ b/source/blender/editors/space_graph/graph_draw.c @@ -33,6 +33,7 @@ #include <float.h> #include "BLI_blenlib.h" +#include "BLI_math.h" #include "BLI_utildefines.h" #include "DNA_anim_types.h" @@ -42,6 +43,7 @@ #include "DNA_userdef_types.h" #include "BKE_context.h" +#include "BKE_curve.h" #include "BKE_fcurve.h" @@ -475,6 +477,7 @@ static void draw_fcurve_samples(SpaceIpo *sipo, ARegion *ar, FCurve *fcu) /* helper func - just draw the F-Curve by sampling the visible region (for drawing curves with modifiers) */ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d, View2DGrid *grid) { + SpaceIpo *sipo = (SpaceIpo *)ac->sl; ChannelDriver *driver; float samplefreq; float stime, etime; @@ -502,7 +505,7 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d * which means that our curves can be as smooth as possible. However, * this does mean that curves may not be fully accurate (i.e. if they have * sudden spikes which happen at the sampling point, we may have problems). - * Also, this may introduce lower performance on less densely detailed curves,' + * Also, this may introduce lower performance on less densely detailed curves, * though it is impossible to predict this from the modifiers! * * If the automatically determined sampling frequency is likely to cause an infinite @@ -512,7 +515,25 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d /* grid->dx represents the number of 'frames' between gridlines, but we divide by U.v2d_min_gridsize to get pixels-steps */ /* TODO: perhaps we should have 1.0 frames as upper limit so that curves don't get too distorted? */ samplefreq = dx / (U.v2d_min_gridsize * U.pixelsize); - if (samplefreq < 0.00001f) samplefreq = 0.00001f; + + if (sipo->flag & SIPO_BEAUTYDRAW_OFF) { + /* Low Precision = coarse lower-bound clamping + * + * Although the "Beauty Draw" flag was originally for AA'd + * line drawing, the sampling rate here has a much greater + * impact on performance (e.g. for T40372)! + * + * This one still amounts to 10 sample-frames for each 1-frame interval + * which should be quite a decent approximation in many situations. + */ + if (samplefreq < 0.1f) + samplefreq = 0.1f; + } + else { + /* "Higher Precision" but slower - especially on larger windows (e.g. T40372) */ + if (samplefreq < 0.00001f) + samplefreq = 0.00001f; + } /* the start/end times are simply the horizontal extents of the 'cur' rect */ @@ -525,12 +546,13 @@ static void draw_fcurve_curve(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d * the displayed values appear correctly in the viewport */ glBegin(GL_LINE_STRIP); - - for (i = 0, n = (etime - stime) / samplefreq + 0.5f; i < n; ++i) { + + n = (etime - stime) / samplefreq + 0.5f; + for (i = 0; i <= n; i++) { float ctime = stime + i * samplefreq; glVertex2f(ctime, evaluate_fcurve(fcu, ctime) * unitFac); } - + glEnd(); /* restore driver */ @@ -616,8 +638,24 @@ static void draw_fcurve_curve_samples(bAnimContext *ac, ID *id, FCurve *fcu, Vie glPopMatrix(); } -#if 0 -/* helper func - draw one repeat of an F-Curve */ +/* helper func - check if the F-Curve only contains easily drawable segments + * (i.e. no easing equation interpolations) + */ +static bool fcurve_can_use_simple_bezt_drawing(FCurve *fcu) +{ + BezTriple *bezt; + int i; + + for (i = 0, bezt = fcu->bezt; i < fcu->totvert; i++, bezt++) { + if (ELEM(bezt->ipo, BEZT_IPO_CONST, BEZT_IPO_LIN, BEZT_IPO_BEZ) == false) { + return false; + } + } + + return true; +} + +/* helper func - draw one repeat of an F-Curve (using Bezier curve approximations) */ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2D *v2d) { BezTriple *prevbezt = fcu->bezt; @@ -629,12 +667,12 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2 int resol; float unit_scale; short mapping_flag = ANIM_get_normalization_flags(ac); - + /* apply unit mapping */ glPushMatrix(); unit_scale = ANIM_unit_mapping_get_factor(ac->scene, id, fcu, mapping_flag); glScalef(1.0f, unit_scale, 1.0f); - + glBegin(GL_LINE_STRIP); /* extrapolate to left? */ @@ -689,17 +727,19 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2 v1[1] = prevbezt->vec[1][1]; glVertex2fv(v1); } - else { + else if (prevbezt->ipo == BEZT_IPO_BEZ) { /* Bezier-Interpolation: draw curve as series of segments between keyframes * - resol determines number of points to sample in between keyframes */ /* resol depends on distance between points (not just horizontal) OR is a fixed high res */ /* TODO: view scale should factor into this someday too... */ - if (fcu->driver) + if (fcu->driver) { resol = 32; - else + } + else { resol = (int)(5.0f * len_v2v2(bezt->vec[1], prevbezt->vec[1])); + } if (resol < 2) { /* only draw one */ @@ -773,7 +813,6 @@ static void draw_fcurve_curve_bezts(bAnimContext *ac, ID *id, FCurve *fcu, View2 glEnd(); glPopMatrix(); } -#endif /* Debugging -------------------------------- */ @@ -989,11 +1028,15 @@ void graph_draw_curves(bAnimContext *ac, SpaceIpo *sipo, ARegion *ar, View2DGrid } else if (((fcu->bezt) || (fcu->fpt)) && (fcu->totvert)) { /* just draw curve based on defined data (i.e. no modifiers) */ - if (fcu->bezt) - //draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d); - draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid); // XXX: better to do an optimised integration here instead, but for now, this works - else if (fcu->fpt) + if (fcu->bezt) { + if (fcurve_can_use_simple_bezt_drawing(fcu)) + draw_fcurve_curve_bezts(ac, ale->id, fcu, &ar->v2d); + else + draw_fcurve_curve(ac, ale->id, fcu, &ar->v2d, grid); + } + else if (fcu->fpt) { draw_fcurve_curve_samples(ac, ale->id, fcu, &ar->v2d); + } } /* restore settings */ @@ -1109,7 +1152,7 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) } } { /* second pass: widgets */ - uiBlock *block = uiBeginBlock(C, ar, __func__, UI_EMBOSS); + uiBlock *block = UI_block_begin(C, ar, __func__, UI_EMBOSS); size_t channel_index = 0; y = (float)ACHANNEL_FIRST; @@ -1135,8 +1178,8 @@ void graph_draw_channel_names(bContext *C, bAnimContext *ac, ARegion *ar) channel_index++; } - uiEndBlock(C, block); - uiDrawBlock(C, block); + UI_block_end(C, block); + UI_block_draw(C, block); glDisable(GL_BLEND); } diff --git a/source/blender/editors/space_graph/graph_edit.c b/source/blender/editors/space_graph/graph_edit.c index c8298927f7d..2ca659252d2 100644 --- a/source/blender/editors/space_graph/graph_edit.c +++ b/source/blender/editors/space_graph/graph_edit.c @@ -60,8 +60,6 @@ #include "BKE_context.h" #include "BKE_report.h" -#include "UI_interface.h" -#include "UI_resources.h" #include "UI_view2d.h" #include "ED_anim_api.h" @@ -1888,7 +1886,7 @@ static int graphkeys_framejump_exec(bContext *C, wmOperator *UNUSED(op)) ked.f1 += current_ked.f1; ked.i1 += current_ked.i1; - ked.f2 += current_ked.f2 / unit_scale; + ked.f2 += current_ked.f2 * unit_scale; ked.i2 += current_ked.i2; } diff --git a/source/blender/editors/space_graph/graph_intern.h b/source/blender/editors/space_graph/graph_intern.h index 408c78d194e..50412952139 100644 --- a/source/blender/editors/space_graph/graph_intern.h +++ b/source/blender/editors/space_graph/graph_intern.h @@ -62,6 +62,7 @@ void graph_draw_ghost_curves(struct bAnimContext *ac, struct SpaceIpo *sipo, str void GRAPH_OT_select_all_toggle(struct wmOperatorType *ot); void GRAPH_OT_select_border(struct wmOperatorType *ot); void GRAPH_OT_select_lasso(struct wmOperatorType *ot); +void GRAPH_OT_select_circle(struct wmOperatorType *ot); void GRAPH_OT_select_column(struct wmOperatorType *ot); void GRAPH_OT_select_linked(struct wmOperatorType *ot); void GRAPH_OT_select_more(struct wmOperatorType *ot); diff --git a/source/blender/editors/space_graph/graph_ops.c b/source/blender/editors/space_graph/graph_ops.c index 62b6b59df29..f06d738200a 100644 --- a/source/blender/editors/space_graph/graph_ops.c +++ b/source/blender/editors/space_graph/graph_ops.c @@ -34,6 +34,7 @@ #include "DNA_scene_types.h" +#include "BLI_blenlib.h" #include "BLI_utildefines.h" #include "BLI_math_base.h" @@ -200,6 +201,174 @@ static void GRAPH_OT_cursor_set(wmOperatorType *ot) RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Value", "", -100.0f, 100.0f); } +/* Hide/Reveal ------------------------------------------------------------ */ + +static int graphview_curves_hide_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + ListBase anim_data = {NULL, NULL}; + ListBase all_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + const bool unselected = RNA_boolean_get(op->ptr, "unselected"); + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* get list of all channels that selection may need to be flushed to + * - hierarchy must not affect what we have access to here... + */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype); + + /* filter data + * - of the remaining visible curves, we want to hide the ones that are + * selected/unselected (depending on "unselected" prop) + */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); + if (unselected) + filter |= ANIMFILTER_UNSEL; + else + filter |= ANIMFILTER_SEL; + + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + for (ale = anim_data.first; ale; ale = ale->next) { + /* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */ + /* TODO: find out why this is the case, and fix that */ + if (ale->type == ANIMTYPE_OBJECT) + continue; + + /* change the hide setting, and unselect it... */ + ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR); + ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_CLEAR); + + /* now, also flush selection status up/down as appropriate */ + ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_CLEAR); + } + + /* cleanup */ + ANIM_animdata_freelist(&anim_data); + BLI_freelistN(&all_data); + + /* unhide selected */ + if (unselected) { + /* turn off requirement for visible */ + filter = ANIMFILTER_SEL | ANIMFILTER_NODUPLIS | ANIMFILTER_LIST_CHANNELS; + + /* flushing has been done */ + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + for (ale = anim_data.first; ale; ale = ale->next) { + /* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */ + /* TODO: find out why this is the case, and fix that */ + if (ale->type == ANIMTYPE_OBJECT) + continue; + + /* change the hide setting, and unselect it... */ + ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD); + ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_ADD); + + /* now, also flush selection status up/down as appropriate */ + ANIM_flush_setting_anim_channels(&ac, &anim_data, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD); + } + ANIM_animdata_freelist(&anim_data); + } + + + /* send notifier that things have changed */ + WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +static void GRAPH_OT_hide(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Hide Curves"; + ot->idname = "GRAPH_OT_hide"; + ot->description = "Hide selected curves from Graph Editor view"; + + /* api callbacks */ + ot->exec = graphview_curves_hide_exec; + ot->poll = ED_operator_graphedit_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; + + /* props */ + RNA_def_boolean(ot->srna, "unselected", 0, "Unselected", "Hide unselected rather than selected curves"); +} + +/* ........ */ + +static int graphview_curves_reveal_exec(bContext *C, wmOperator *UNUSED(op)) +{ + bAnimContext ac; + ListBase anim_data = {NULL, NULL}; + ListBase all_data = {NULL, NULL}; + bAnimListElem *ale; + int filter; + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + /* get list of all channels that selection may need to be flushed to + * - hierarchy must not affect what we have access to here... + */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_CHANNELS | ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(&ac, &all_data, filter, ac.data, ac.datatype); + + /* filter data + * - just go through all visible channels, ensuring that everything is set to be curve-visible + */ + filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_NODUPLIS); + ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype); + + for (ale = anim_data.first; ale; ale = ale->next) { + /* hack: skip object channels for now, since flushing those will always flush everything, but they are always included */ + /* TODO: find out why this is the case, and fix that */ + if (ale->type == ANIMTYPE_OBJECT) + continue; + + /* select if it is not visible */ + if (ANIM_channel_setting_get(&ac, ale, ACHANNEL_SETTING_VISIBLE) == 0) + ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_SELECT, ACHANNEL_SETFLAG_ADD); + + /* change the visibility setting */ + ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, ACHANNEL_SETFLAG_ADD); + + /* now, also flush selection status up/down as appropriate */ + ANIM_flush_setting_anim_channels(&ac, &all_data, ale, ACHANNEL_SETTING_VISIBLE, true); + } + + /* cleanup */ + ANIM_animdata_freelist(&anim_data); + BLI_freelistN(&all_data); + + /* send notifier that things have changed */ + WM_event_add_notifier(C, NC_ANIMATION | ND_ANIMCHAN | NA_EDITED, NULL); + + return OPERATOR_FINISHED; +} + +static void GRAPH_OT_reveal(wmOperatorType *ot) +{ + /* identifiers */ + ot->name = "Reveal Curves"; + ot->idname = "GRAPH_OT_reveal"; + ot->description = "Make previously hidden curves visible again in Graph Editor view"; + + /* api callbacks */ + ot->exec = graphview_curves_reveal_exec; + ot->poll = ED_operator_graphedit_active; + + /* flags */ + ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; +} + /* ************************** registration - operator types **********************************/ void graphedit_operatortypes(void) @@ -215,12 +384,16 @@ void graphedit_operatortypes(void) WM_operatortype_append(GRAPH_OT_ghost_curves_create); WM_operatortype_append(GRAPH_OT_ghost_curves_clear); + WM_operatortype_append(GRAPH_OT_hide); + WM_operatortype_append(GRAPH_OT_reveal); + /* keyframes */ /* selection */ 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_lasso); + WM_operatortype_append(GRAPH_OT_select_circle); WM_operatortype_append(GRAPH_OT_select_column); WM_operatortype_append(GRAPH_OT_select_linked); WM_operatortype_append(GRAPH_OT_select_more); @@ -359,6 +532,8 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) kmi = WM_keymap_add_item(keymap, "GRAPH_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT, 0); RNA_boolean_set(kmi->ptr, "deselect", true); + WM_keymap_add_item(keymap, "GRAPH_OT_select_circle", CKEY, KM_PRESS, 0, 0); + /* column select */ 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); @@ -429,6 +604,19 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) /* transform system */ transform_keymap_for_space(keyconf, keymap, SPACE_IPO); + /* pivot point settings */ + kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", COMMAKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point"); + RNA_string_set(kmi->ptr, "value", "BOUNDING_BOX_CENTER"); + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, 0, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point"); + RNA_string_set(kmi->ptr, "value", "CURSOR"); + + kmi = WM_keymap_add_item(keymap, "WM_OT_context_set_enum", PERIODKEY, KM_PRESS, KM_CTRL, 0); + RNA_string_set(kmi->ptr, "data_path", "space_data.pivot_point"); + RNA_string_set(kmi->ptr, "value", "INDIVIDUAL_ORIGINS"); + /* special markers hotkeys for anim editors: see note in definition of this function */ ED_marker_keymap_animedit_conflictfree(keymap); } @@ -438,6 +626,7 @@ static void graphedit_keymap_keyframes(wmKeyConfig *keyconf, wmKeyMap *keymap) void graphedit_keymap(wmKeyConfig *keyconf) { wmKeyMap *keymap; + wmKeyMapItem *kmi; /* keymap for all regions */ keymap = WM_keymap_find(keyconf, "Graph Editor Generic", SPACE_IPO, 0); @@ -448,7 +637,17 @@ void graphedit_keymap(wmKeyConfig *keyconf) /* find (i.e. a shortcut for setting the name filter) */ WM_keymap_add_item(keymap, "ANIM_OT_channels_find", FKEY, KM_PRESS, KM_CTRL, 0); - + + /* hide/reveal selected curves */ + kmi = WM_keymap_add_item(keymap, "GRAPH_OT_hide", HKEY, KM_PRESS, 0, 0); + RNA_boolean_set(kmi->ptr, "unselected", false); + + kmi = WM_keymap_add_item(keymap, "GRAPH_OT_hide", HKEY, KM_PRESS, KM_SHIFT, 0); + RNA_boolean_set(kmi->ptr, "unselected", true); + + WM_keymap_add_item(keymap, "GRAPH_OT_reveal", HKEY, KM_PRESS, KM_ALT, 0); + + /* channels */ /* Channels are not directly handled by the Graph Editor module, but are inherited from the Animation module. * All the relevant operations, keymaps, drawing, etc. can therefore all be found in that module instead, as these diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c index 378139accbc..78dbae7618b 100644 --- a/source/blender/editors/space_graph/graph_select.c +++ b/source/blender/editors/space_graph/graph_select.c @@ -219,7 +219,7 @@ void GRAPH_OT_select_all_toggle(wmOperatorType *ot) */ static void borderselect_graphkeys( bAnimContext *ac, const rctf *rectf_view, short mode, short selectmode, bool incl_handles, - struct KeyframeEdit_LassoData *data_lasso) + void *data) { ListBase anim_data = {NULL, NULL}; bAnimListElem *ale; @@ -244,10 +244,16 @@ static void borderselect_graphkeys( /* init editing data */ memset(&ked, 0, sizeof(KeyframeEditData)); - if (data_lasso) { + if (mode == BEZT_OK_REGION_LASSO) { + struct KeyframeEdit_LassoData *data_lasso = data; data_lasso->rectf_scaled = &scaled_rectf; ked.data = data_lasso; } + else if (mode == BEZT_OK_REGION_CIRCLE) { + struct KeyframeEdit_CircleData *data_circle = data; + data_circle->rectf_scaled = &scaled_rectf; + ked.data = data; + } else { ked.data = &scaled_rectf; } @@ -485,6 +491,81 @@ void GRAPH_OT_select_lasso(wmOperatorType *ot) RNA_def_boolean(ot->srna, "extend", true, "Extend", "Extend selection instead of deselecting everything first"); } +static int graph_circle_select_exec(bContext *C, wmOperator *op) +{ + bAnimContext ac; + const int gesture_mode = RNA_int_get(op->ptr, "gesture_mode"); + short selectmode; + bool incl_handles; + rctf rect_fl; + struct KeyframeEdit_CircleData data; + float x = RNA_int_get(op->ptr, "x"); + float y = RNA_int_get(op->ptr, "y"); + float radius = RNA_int_get(op->ptr, "radius"); + + /* get editor data */ + if (ANIM_animdata_get_context(C, &ac) == 0) + return OPERATOR_CANCELLED; + + data.mval[0] = x; + data.mval[1] = y; + data.radius_squared = radius * radius; + data.rectf_view = &rect_fl; + + if (gesture_mode == GESTURE_MODAL_SELECT) + selectmode = SELECT_ADD; + else + selectmode = SELECT_SUBTRACT; + + rect_fl.xmin = x - radius; + rect_fl.xmax = x + radius; + rect_fl.ymin = y - radius; + rect_fl.ymax = y + radius; + + if (ac.spacetype == SPACE_IPO) { + SpaceIpo *sipo = (SpaceIpo *)ac.sl; + if (selectmode == SELECT_ADD) { + incl_handles = ((sipo->flag & SIPO_SELVHANDLESONLY) || + (sipo->flag & SIPO_NOHANDLES)) == 0; + } + else { + incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0; + } + } + else { + incl_handles = false; + } + + /* apply borderselect action */ + borderselect_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_CIRCLE, selectmode, incl_handles, &data); + + /* send notifier that keyframe selection has changed */ + WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); + + return OPERATOR_FINISHED; +} + +void GRAPH_OT_select_circle(wmOperatorType *ot) +{ + ot->name = "Circle Select"; + ot->description = "Select keyframe points using circle selection"; + ot->idname = "GRAPH_OT_select_circle"; + + ot->invoke = WM_gesture_circle_invoke; + ot->modal = WM_gesture_circle_modal; + ot->exec = graph_circle_select_exec; + ot->poll = graphop_visible_keyframes_poll; + ot->cancel = WM_gesture_circle_cancel; + + /* flags */ + ot->flag = OPTYPE_UNDO; + + RNA_def_int(ot->srna, "x", 0, INT_MIN, INT_MAX, "X", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "y", 0, INT_MIN, INT_MAX, "Y", "", INT_MIN, INT_MAX); + RNA_def_int(ot->srna, "radius", 1, 1, INT_MAX, "Radius", "", 1, INT_MAX); + RNA_def_int(ot->srna, "gesture_mode", 0, INT_MIN, INT_MAX, "Event Type", "", INT_MIN, INT_MAX); +} + /* ******************** Column Select Operator **************************** */ /* This operator works in one of four ways: * - 1) select all keyframes in the same frame as a selected one (KKEY) diff --git a/source/blender/editors/space_graph/graph_utils.c b/source/blender/editors/space_graph/graph_utils.c index e9c8ae95acd..eea360ced45 100644 --- a/source/blender/editors/space_graph/graph_utils.c +++ b/source/blender/editors/space_graph/graph_utils.c @@ -40,7 +40,6 @@ #include "MEM_guardedalloc.h" -#include "BLI_math.h" #include "BLI_blenlib.h" #include "BKE_context.h" diff --git a/source/blender/editors/space_graph/space_graph.c b/source/blender/editors/space_graph/space_graph.c index 6dba706b241..ad6f3ff5c7e 100644 --- a/source/blender/editors/space_graph/space_graph.c +++ b/source/blender/editors/space_graph/space_graph.c @@ -182,7 +182,7 @@ static void graph_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa) { SpaceIpo *sipo = (SpaceIpo *)sa->spacedata.first; - /* init dopesheet data if non-existant (i.e. for old files) */ + /* init dopesheet data if non-existent (i.e. for old files) */ if (sipo->ads == NULL) { sipo->ads = MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet"); sipo->ads->source = (ID *)(G.main->scene.first); // FIXME: this is a really nasty hack here for now... @@ -293,7 +293,7 @@ static void graph_main_area_draw(const bContext *C, ARegion *ar) /* markers */ UI_view2d_view_orthoSpecial(ar, v2d, 1); - draw_markers_time(C, 0); + ED_markers_draw(C, DRAW_MARKERS_MARGIN); /* preview range */ UI_view2d_view_ortho(v2d); |