Changeset View
Changeset View
Standalone View
Standalone View
source/blender/editors/space_graph/graph_select.c
| Show First 20 Lines • Show All 495 Lines • ▼ Show 20 Lines | |||||
| * -> ALT-BKEY - depending on which axis of the region was larger... | * -> ALT-BKEY - depending on which axis of the region was larger... | ||||
| * -> 2) x-axis, so select all frames within frame range (validation with BEZT_OK_FRAMERANGE) | * -> 2) x-axis, so select all frames within frame range (validation with BEZT_OK_FRAMERANGE) | ||||
| * -> 3) y-axis, so select all frames within channels that region included | * -> 3) y-axis, so select all frames within channels that region included | ||||
| * (validation with BEZT_OK_VALUERANGE). | * (validation with BEZT_OK_VALUERANGE). | ||||
| * | * | ||||
| * The selection backend is also reused for the Lasso and Circle select operators. | * The selection backend is also reused for the Lasso and Circle select operators. | ||||
| */ | */ | ||||
| /* Box Select only selects keyframes now, as overshooting handles often get caught too, | static rctf initialize_box_select_coords(const bAnimContext *ac, const rctf *rectf_view) | ||||
| * which means that they may be inadvertently moved as well. However, incl_handles overrides | |||||
| * this, and allow handles to be considered independently too. | |||||
| * Also, for convenience, handles should get same status as keyframe (if it was within bounds). | |||||
| */ | |||||
| static void box_select_graphkeys(bAnimContext *ac, | |||||
| const rctf *rectf_view, | |||||
| short mode, | |||||
| short selectmode, | |||||
| bool incl_handles, | |||||
| void *data) | |||||
| { | { | ||||
| ListBase anim_data = {NULL, NULL}; | const View2D *v2d = &ac->region->v2d; | ||||
| bAnimListElem *ale; | rctf rectf; | ||||
| int filter, mapping_flag; | |||||
| SpaceGraph *sipo = (SpaceGraph *)ac->sl; | |||||
| KeyframeEditData ked; | |||||
| KeyframeEditFunc ok_cb, select_cb; | |||||
| View2D *v2d = &ac->region->v2d; | |||||
| rctf rectf, scaled_rectf; | |||||
| /* Convert mouse coordinates to frame ranges and | /* Convert mouse coordinates to frame ranges and | ||||
| * channel coordinates corrected for view pan/zoom. */ | * channel coordinates corrected for view pan/zoom. */ | ||||
| UI_view2d_region_to_view_rctf(v2d, rectf_view, &rectf); | UI_view2d_region_to_view_rctf(v2d, rectf_view, &rectf); | ||||
| return rectf; | |||||
| } | |||||
| /* filter data */ | static ListBase initialize_box_select_anim_data(bAnimContext *ac) | ||||
| filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); | { | ||||
| ListBase anim_data = {NULL, NULL}; | |||||
sybren: Is there really a necessity to have this many parameters? To me it's an indication that this… | |||||
Done Inline ActionsOutput parameters must be prefixed with r_. sybren: Output parameters must be prefixed with `r_`. | |||||
Done Inline Actionsr_filter isn't used in either of the calls, so it doesn't need to be returned at all. sybren: `r_filter` isn't used in either of the calls, so it doesn't need to be returned at all. | |||||
| const int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS); | |||||
| ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); | ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype); | ||||
| /* get beztriple editing/validation funcs */ | return anim_data; | ||||
| select_cb = ANIM_editkeyframes_select(selectmode); | } | ||||
| ok_cb = ANIM_editkeyframes_ok(mode); | |||||
| /* init editing data */ | static void initialize_box_select_key_editing_data(const SpaceGraph *sipo, | ||||
| memset(&ked, 0, sizeof(KeyframeEditData)); | const bool incl_handles, | ||||
| if (mode == BEZT_OK_REGION_LASSO) { | const short mode, | ||||
| bAnimContext *ac, | |||||
| void *data, | |||||
| rctf *scaled_rectf, | |||||
| KeyframeEditData *r_ked, | |||||
| int *r_mapping_flag) | |||||
| { | |||||
| memset(r_ked, 0, sizeof(KeyframeEditData)); | |||||
| switch (mode) { | |||||
| case BEZT_OK_REGION_LASSO: { | |||||
| KeyframeEdit_LassoData *data_lasso = data; | KeyframeEdit_LassoData *data_lasso = data; | ||||
| data_lasso->rectf_scaled = &scaled_rectf; | data_lasso->rectf_scaled = scaled_rectf; | ||||
| ked.data = data_lasso; | r_ked->data = data_lasso; | ||||
| break; | |||||
| } | } | ||||
| else if (mode == BEZT_OK_REGION_CIRCLE) { | case BEZT_OK_REGION_CIRCLE: { | ||||
| KeyframeEdit_CircleData *data_circle = data; | KeyframeEdit_CircleData *data_circle = data; | ||||
| data_circle->rectf_scaled = &scaled_rectf; | data_circle->rectf_scaled = scaled_rectf; | ||||
| ked.data = data; | r_ked->data = data_circle; | ||||
| break; | |||||
| } | } | ||||
| else { | default: | ||||
| ked.data = &scaled_rectf; | r_ked->data = scaled_rectf; | ||||
| break; | |||||
| } | } | ||||
| if (sipo->flag & SIPO_SELVHANDLESONLY) { | if (sipo->flag & SIPO_SELVHANDLESONLY) { | ||||
| ked.iterflags |= KEYFRAME_ITER_HANDLES_DEFAULT_INVISIBLE; | r_ked->iterflags |= KEYFRAME_ITER_HANDLES_DEFAULT_INVISIBLE; | ||||
| } | } | ||||
| /* treat handles separately? */ | /* Enable handles selection. (used in keyframes_edit.c > KEYFRAME_OK_CHECKS macro) */ | ||||
Done Inline ActionsI have no clue what this comment means. Do you? Maybe then you could reword it to make more sense. sybren: I have no clue what this comment means. Do you? Maybe then you could reword it to make more… | |||||
| if (incl_handles) { | if (incl_handles) { | ||||
| ked.iterflags |= KEYFRAME_ITER_INCL_HANDLES; | r_ked->iterflags |= KEYFRAME_ITER_INCL_HANDLES; | ||||
| mapping_flag = 0; | *r_mapping_flag = 0; | ||||
| } | } | ||||
| else { | else { | ||||
| mapping_flag = ANIM_UNITCONV_ONLYKEYS; | *r_mapping_flag = ANIM_UNITCONV_ONLYKEYS; | ||||
| } | } | ||||
| mapping_flag |= ANIM_get_normalization_flags(ac); | *r_mapping_flag |= ANIM_get_normalization_flags(ac); | ||||
| } | |||||
| /* Box Select only selects keyframes, as overshooting handles often get caught too, | |||||
| * which means that they may be inadvertently moved as well. However, incl_handles overrides | |||||
| * this, and allow handles to be considered independently too. | |||||
| * Also, for convenience, handles should get same status as keyframe (if it was within bounds). | |||||
| */ | |||||
| static void box_select_graphkeys(bAnimContext *ac, | |||||
| const rctf *rectf_view, | |||||
| short mode, | |||||
| short selectmode, | |||||
| bool incl_handles, | |||||
| void *data) | |||||
| { | |||||
| const rctf rectf = initialize_box_select_coords(ac, rectf_view); | |||||
| ListBase anim_data = initialize_box_select_anim_data(ac); | |||||
| SpaceGraph *sipo = (SpaceGraph *)ac->sl; | |||||
| rctf scaled_rectf; | |||||
| KeyframeEditData ked; | |||||
| int mapping_flag; | |||||
| initialize_box_select_key_editing_data( | |||||
| sipo, incl_handles, mode, ac, data, &scaled_rectf, &ked, &mapping_flag); | |||||
| /* Get beztriple editing/validation funcs. */ | |||||
| const KeyframeEditFunc select_cb = ANIM_editkeyframes_select(selectmode); | |||||
| const KeyframeEditFunc ok_cb = ANIM_editkeyframes_ok(mode); | |||||
| /* loop over data, doing box select */ | /* Try selecting the keyframes. */ | ||||
| bAnimListElem *ale = NULL; | |||||
| /* First loop over data, doing box select. try selecting keys only. */ | |||||
| for (ale = anim_data.first; ale; ale = ale->next) { | for (ale = anim_data.first; ale; ale = ale->next) { | ||||
| AnimData *adt = ANIM_nla_mapping_get(ac, ale); | AnimData *adt = ANIM_nla_mapping_get(ac, ale); | ||||
| FCurve *fcu = (FCurve *)ale->key_data; | FCurve *fcu = (FCurve *)ale->key_data; | ||||
| float offset; | float offset; | ||||
| float unit_scale = ANIM_unit_mapping_get_factor( | const float unit_scale = ANIM_unit_mapping_get_factor( | ||||
| ac->scene, ale->id, fcu, mapping_flag, &offset); | ac->scene, ale->id, fcu, mapping_flag, &offset); | ||||
| /* apply NLA mapping to all the keyframes, since it's easier than trying to | /* Apply NLA mapping to all the keyframes, since it's easier than trying to | ||||
| * guess when a callback might use something different | * guess when a callback might use something different. | ||||
| */ | */ | ||||
| if (adt) { | if (adt) { | ||||
| ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, incl_handles == 0); | ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, incl_handles == 0); | ||||
| } | } | ||||
| scaled_rectf.xmin = rectf.xmin; | scaled_rectf.xmin = rectf.xmin; | ||||
| scaled_rectf.xmax = rectf.xmax; | scaled_rectf.xmax = rectf.xmax; | ||||
| scaled_rectf.ymin = rectf.ymin / unit_scale - offset; | scaled_rectf.ymin = rectf.ymin / unit_scale - offset; | ||||
| scaled_rectf.ymax = rectf.ymax / unit_scale - offset; | scaled_rectf.ymax = rectf.ymax / unit_scale - offset; | ||||
| /* set horizontal range (if applicable) | /* Set horizontal range (if applicable). | ||||
| * NOTE: these values are only used for x-range and y-range but not region | * NOTE: these values are only used for x-range and y-range but not region | ||||
| * (which uses ked.data, i.e. rectf) | * (which uses ked.data, i.e. rectf) | ||||
| */ | */ | ||||
| if (mode != BEZT_OK_VALUERANGE) { | if (mode != BEZT_OK_VALUERANGE) { | ||||
| ked.f1 = rectf.xmin; | ked.f1 = rectf.xmin; | ||||
| ked.f2 = rectf.xmax; | ked.f2 = rectf.xmax; | ||||
| } | } | ||||
| else { | else { | ||||
| ked.f1 = rectf.ymin; | ked.f1 = rectf.ymin; | ||||
| ked.f2 = rectf.ymax; | ked.f2 = rectf.ymax; | ||||
| } | } | ||||
| /* firstly, check if any keyframes will be hit by this */ | /* Firstly, check if any keyframes will be hit by this. */ | ||||
| if (ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, ok_cb, NULL)) { | if (ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, ok_cb, NULL)) { | ||||
| /* select keyframes that are in the appropriate places */ | /* select keyframes that are in the appropriate places */ | ||||
| ANIM_fcurve_keyframes_loop(&ked, fcu, ok_cb, select_cb, NULL); | ANIM_fcurve_keyframes_loop(&ked, fcu, ok_cb, select_cb, NULL); | ||||
| /* Only change selection of channel when the visibility of keyframes | /* Only change selection of channel when the visibility of keyframes | ||||
| * doesn't depend on this. */ | * doesn't depend on this. */ | ||||
| if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) { | if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) { | ||||
| /* select the curve too now that curve will be touched */ | /* select the curve too now that curve will be touched */ | ||||
| if (selectmode == SELECT_ADD) { | if (selectmode == SELECT_ADD) { | ||||
| fcu->flag |= FCURVE_SELECTED; | fcu->flag |= FCURVE_SELECTED; | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| /* un-apply NLA mapping from all the keyframes */ | /* Un-apply NLA mapping from all the keyframes. */ | ||||
| if (adt) { | if (adt) { | ||||
| ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, incl_handles == 0); | ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, incl_handles == 0); | ||||
| } | } | ||||
| } | } | ||||
| /* cleanup */ | /* Cleanup. */ | ||||
| ANIM_animdata_freelist(&anim_data); | ANIM_animdata_freelist(&anim_data); | ||||
| } | } | ||||
| /* ------------------- */ | /* ------------------- */ | ||||
| static int graphkeys_box_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) | static int graphkeys_box_select_invoke(bContext *C, wmOperator *op, const wmEvent *event) | ||||
| { | { | ||||
| bAnimContext ac; | bAnimContext ac; | ||||
| Show All 32 Lines | static int graphkeys_box_select_exec(bContext *C, wmOperator *op) | ||||
| const int selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT; | const int selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT; | ||||
| if (SEL_OP_USE_PRE_DESELECT(sel_op)) { | if (SEL_OP_USE_PRE_DESELECT(sel_op)) { | ||||
| deselect_graph_keys(&ac, 1, SELECT_SUBTRACT, true); | deselect_graph_keys(&ac, 1, SELECT_SUBTRACT, true); | ||||
| } | } | ||||
| /* 'include_handles' from the operator specifies whether to include handles in the selection. */ | /* 'include_handles' from the operator specifies whether to include handles in the selection. */ | ||||
| const bool incl_handles = RNA_boolean_get(op->ptr, "include_handles"); | const bool incl_handles = RNA_boolean_get(op->ptr, "include_handles"); | ||||
| /* get settings from operator */ | /* Get settings from operator. */ | ||||
| WM_operator_properties_border_to_rcti(op, &rect); | WM_operator_properties_border_to_rcti(op, &rect); | ||||
| /* selection 'mode' depends on whether box_select region only matters on one axis */ | /* Selection 'mode' depends on whether box_select region only matters on one axis. */ | ||||
| if (RNA_boolean_get(op->ptr, "axis_range")) { | if (RNA_boolean_get(op->ptr, "axis_range")) { | ||||
| /* mode depends on which axis of the range is larger to determine which axis to use | /* Mode depends on which axis of the range is larger to determine which axis to use | ||||
| * - Checking this in region-space is fine, as it's fundamentally still going to be a | * - Checking this in region-space is fine, as it's fundamentally still going to be a | ||||
| * different rect size. | * different rect size. | ||||
| * - The frame-range select option is favored over the channel one (x over y), | * - The frame-range select option is favored over the channel one (x over y), | ||||
| * as frame-range one is often used for tweaking timing when "blocking", | * as frame-range one is often used for tweaking timing when "blocking", | ||||
| * while channels is not that useful. | * while channels is not that useful. | ||||
| */ | */ | ||||
| if ((BLI_rcti_size_x(&rect)) >= (BLI_rcti_size_y(&rect))) { | if ((BLI_rcti_size_x(&rect)) >= (BLI_rcti_size_y(&rect))) { | ||||
| mode = BEZT_OK_FRAMERANGE; | mode = BEZT_OK_FRAMERANGE; | ||||
| } | } | ||||
| else { | else { | ||||
| mode = BEZT_OK_VALUERANGE; | mode = BEZT_OK_VALUERANGE; | ||||
| } | } | ||||
| } | } | ||||
| else { | else { | ||||
| mode = BEZT_OK_REGION; | mode = BEZT_OK_REGION; | ||||
| } | } | ||||
| BLI_rctf_rcti_copy(&rect_fl, &rect); | BLI_rctf_rcti_copy(&rect_fl, &rect); | ||||
| /* apply box_select action */ | /* Apply box_select action. */ | ||||
| box_select_graphkeys(&ac, &rect_fl, mode, selectmode, incl_handles, NULL); | box_select_graphkeys(&ac, &rect_fl, mode, selectmode, incl_handles, NULL); | ||||
| /* Send notifier that keyframe selection has changed. */ | |||||
| /* send notifier that keyframe selection has changed */ | |||||
| WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void GRAPH_OT_select_box(wmOperatorType *ot) | void GRAPH_OT_select_box(wmOperatorType *ot) | ||||
| { | { | ||||
| /* identifiers */ | /* Identifiers. */ | ||||
| ot->name = "Box Select"; | ot->name = "Box Select"; | ||||
| ot->idname = "GRAPH_OT_select_box"; | ot->idname = "GRAPH_OT_select_box"; | ||||
| ot->description = "Select all keyframes within the specified region"; | ot->description = "Select all keyframes within the specified region"; | ||||
| /* api callbacks */ | /* Api callbacks. */ | ||||
| ot->invoke = graphkeys_box_select_invoke; | ot->invoke = graphkeys_box_select_invoke; | ||||
| ot->exec = graphkeys_box_select_exec; | ot->exec = graphkeys_box_select_exec; | ||||
| ot->modal = WM_gesture_box_modal; | ot->modal = WM_gesture_box_modal; | ||||
| ot->cancel = WM_gesture_box_cancel; | ot->cancel = WM_gesture_box_cancel; | ||||
| ot->poll = graphop_visible_keyframes_poll; | ot->poll = graphop_visible_keyframes_poll; | ||||
| /* flags */ | /* Flags. */ | ||||
| ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO; | ||||
| /* properties */ | /* Properties. */ | ||||
| ot->prop = RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", ""); | ot->prop = RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", ""); | ||||
| RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); | RNA_def_property_flag(ot->prop, PROP_SKIP_SAVE); | ||||
| PropertyRNA *prop; | PropertyRNA *prop; | ||||
| prop = RNA_def_boolean(ot->srna, | prop = RNA_def_boolean(ot->srna, | ||||
| "include_handles", | "include_handles", | ||||
| true, | true, | ||||
| "Include Handles", | "Include Handles", | ||||
| Show All 15 Lines | static int graphkeys_lassoselect_exec(bContext *C, wmOperator *op) | ||||
| bAnimContext ac; | bAnimContext ac; | ||||
| KeyframeEdit_LassoData data_lasso = {0}; | KeyframeEdit_LassoData data_lasso = {0}; | ||||
| rcti rect; | rcti rect; | ||||
| rctf rect_fl; | rctf rect_fl; | ||||
| bool incl_handles; | bool incl_handles; | ||||
| /* get editor data */ | /* Get editor data. */ | ||||
| if (ANIM_animdata_get_context(C, &ac) == 0) { | if (ANIM_animdata_get_context(C, &ac) == 0) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| data_lasso.rectf_view = &rect_fl; | data_lasso.rectf_view = &rect_fl; | ||||
| data_lasso.mcoords = WM_gesture_lasso_path_to_array(C, op, &data_lasso.mcoords_len); | data_lasso.mcoords = WM_gesture_lasso_path_to_array(C, op, &data_lasso.mcoords_len); | ||||
| if (data_lasso.mcoords == NULL) { | if (data_lasso.mcoords == NULL) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| Show All 10 Lines | if (SEL_OP_USE_PRE_DESELECT(sel_op)) { | ||||
| if (selectmode == SELECT_ADD) { | if (selectmode == SELECT_ADD) { | ||||
| incl_handles = ((sipo->flag & SIPO_SELVHANDLESONLY) || (sipo->flag & SIPO_NOHANDLES)) == 0; | incl_handles = ((sipo->flag & SIPO_SELVHANDLESONLY) || (sipo->flag & SIPO_NOHANDLES)) == 0; | ||||
| } | } | ||||
| else { | else { | ||||
| incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0; | incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0; | ||||
| } | } | ||||
| } | } | ||||
| /* get settings from operator */ | /* Get settings from operator. */ | ||||
| BLI_lasso_boundbox(&rect, data_lasso.mcoords, data_lasso.mcoords_len); | BLI_lasso_boundbox(&rect, data_lasso.mcoords, data_lasso.mcoords_len); | ||||
| BLI_rctf_rcti_copy(&rect_fl, &rect); | BLI_rctf_rcti_copy(&rect_fl, &rect); | ||||
| /* apply box_select action */ | /* Apply box_select action. */ | ||||
| box_select_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_LASSO, selectmode, incl_handles, &data_lasso); | box_select_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_LASSO, selectmode, incl_handles, &data_lasso); | ||||
| MEM_freeN((void *)data_lasso.mcoords); | MEM_freeN((void *)data_lasso.mcoords); | ||||
| /* send notifier that keyframe selection has changed */ | /* Send notifier that keyframe selection has changed. */ | ||||
| WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void GRAPH_OT_select_lasso(wmOperatorType *ot) | void GRAPH_OT_select_lasso(wmOperatorType *ot) | ||||
| { | { | ||||
| /* identifiers */ | /* identifiers */ | ||||
| Show All 25 Lines | static int graph_circle_select_exec(bContext *C, wmOperator *op) | ||||
| KeyframeEdit_CircleData data = {0}; | KeyframeEdit_CircleData data = {0}; | ||||
| rctf rect_fl; | rctf rect_fl; | ||||
| float x = RNA_int_get(op->ptr, "x"); | float x = RNA_int_get(op->ptr, "x"); | ||||
| float y = RNA_int_get(op->ptr, "y"); | float y = RNA_int_get(op->ptr, "y"); | ||||
| float radius = RNA_int_get(op->ptr, "radius"); | float radius = RNA_int_get(op->ptr, "radius"); | ||||
| /* get editor data */ | /* Get editor data. */ | ||||
| if (ANIM_animdata_get_context(C, &ac) == 0) { | if (ANIM_animdata_get_context(C, &ac) == 0) { | ||||
| return OPERATOR_CANCELLED; | return OPERATOR_CANCELLED; | ||||
| } | } | ||||
| const eSelectOp sel_op = ED_select_op_modal(RNA_enum_get(op->ptr, "mode"), | const eSelectOp sel_op = ED_select_op_modal(RNA_enum_get(op->ptr, "mode"), | ||||
| WM_gesture_is_modal_first(op->customdata)); | WM_gesture_is_modal_first(op->customdata)); | ||||
| const short selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT; | const short selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT; | ||||
| if (SEL_OP_USE_PRE_DESELECT(sel_op)) { | if (SEL_OP_USE_PRE_DESELECT(sel_op)) { | ||||
| deselect_graph_keys(&ac, 0, SELECT_SUBTRACT, true); | deselect_graph_keys(&ac, 0, SELECT_SUBTRACT, true); | ||||
| } | } | ||||
| data.mval[0] = x; | data.mval[0] = x; | ||||
| data.mval[1] = y; | data.mval[1] = y; | ||||
| data.radius_squared = radius * radius; | data.radius_squared = radius * radius; | ||||
| data.rectf_view = &rect_fl; | data.rectf_view = &rect_fl; | ||||
| rect_fl.xmin = x - radius; | rect_fl.xmin = x - radius; | ||||
| rect_fl.xmax = x + radius; | rect_fl.xmax = x + radius; | ||||
| rect_fl.ymin = y - radius; | rect_fl.ymin = y - radius; | ||||
| rect_fl.ymax = y + radius; | rect_fl.ymax = y + radius; | ||||
| { | { | ||||
| SpaceGraph *sipo = (SpaceGraph *)ac.sl; | SpaceGraph *sipo = (SpaceGraph *)ac.sl; | ||||
| if (selectmode == SELECT_ADD) { | if (selectmode == SELECT_ADD) { | ||||
| incl_handles = ((sipo->flag & SIPO_SELVHANDLESONLY) || (sipo->flag & SIPO_NOHANDLES)) == 0; | incl_handles = ((sipo->flag & SIPO_SELVHANDLESONLY) || (sipo->flag & SIPO_NOHANDLES)) == 0; | ||||
| } | } | ||||
| else { | else { | ||||
| incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0; | incl_handles = (sipo->flag & SIPO_NOHANDLES) == 0; | ||||
| } | } | ||||
| } | } | ||||
| /* apply box_select action */ | /* Apply box_select action. */ | ||||
| box_select_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_CIRCLE, selectmode, incl_handles, &data); | box_select_graphkeys(&ac, &rect_fl, BEZT_OK_REGION_CIRCLE, selectmode, incl_handles, &data); | ||||
| /* Send notifier that keyframe selection has changed. */ | |||||
| /* send notifier that keyframe selection has changed */ | |||||
| WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); | WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL); | ||||
| return OPERATOR_FINISHED; | return OPERATOR_FINISHED; | ||||
| } | } | ||||
| void GRAPH_OT_select_circle(wmOperatorType *ot) | void GRAPH_OT_select_circle(wmOperatorType *ot) | ||||
| { | { | ||||
| ot->name = "Circle Select"; | ot->name = "Circle Select"; | ||||
| ot->description = "Select keyframe points using circle selection"; | ot->description = "Select keyframe points using circle selection"; | ||||
| ot->idname = "GRAPH_OT_select_circle"; | ot->idname = "GRAPH_OT_select_circle"; | ||||
| ot->invoke = WM_gesture_circle_invoke; | ot->invoke = WM_gesture_circle_invoke; | ||||
| ot->modal = WM_gesture_circle_modal; | ot->modal = WM_gesture_circle_modal; | ||||
| ot->exec = graph_circle_select_exec; | ot->exec = graph_circle_select_exec; | ||||
| ot->poll = graphop_visible_keyframes_poll; | ot->poll = graphop_visible_keyframes_poll; | ||||
| ot->cancel = WM_gesture_circle_cancel; | ot->cancel = WM_gesture_circle_cancel; | ||||
| /* flags */ | /* Flags. */ | ||||
| ot->flag = OPTYPE_UNDO; | ot->flag = OPTYPE_UNDO; | ||||
| /* properties */ | /* Properties. */ | ||||
| WM_operator_properties_gesture_circle(ot); | WM_operator_properties_gesture_circle(ot); | ||||
| WM_operator_properties_select_operation_simple(ot); | WM_operator_properties_select_operation_simple(ot); | ||||
| } | } | ||||
| /* ******************** Column Select Operator **************************** */ | /* ******************** Column Select Operator **************************** */ | ||||
| /* This operator works in one of four ways: | /* This operator works in one of four ways: | ||||
| * - 1) select all keyframes in the same frame as a selected one (KKEY) | * - 1) select all keyframes in the same frame as a selected one (KKEY) | ||||
| * - 2) select all keyframes in the same frame as the current frame marker (CTRL-KKEY) | * - 2) select all keyframes in the same frame as the current frame marker (CTRL-KKEY) | ||||
| ▲ Show 20 Lines • Show All 866 Lines • Show Last 20 Lines | |||||
Is there really a necessity to have this many parameters? To me it's an indication that this function is trying to do too many things at the same time. If some (input, output) parameter pairs are independent of the others, use a separate function to initialise them, instead of trying to do everything in one big function.
If there is no way around this, I think it would be best to at least order them such that all input parameters are listed first, and the output parameters are listed last, and to have as many parameters as possible declared const.