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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_graph/graph_select.c')
-rw-r--r--source/blender/editors/space_graph/graph_select.c145
1 files changed, 116 insertions, 29 deletions
diff --git a/source/blender/editors/space_graph/graph_select.c b/source/blender/editors/space_graph/graph_select.c
index 378139accbc..67274100312 100644
--- a/source/blender/editors/space_graph/graph_select.c
+++ b/source/blender/editors/space_graph/graph_select.c
@@ -198,7 +198,7 @@ void GRAPH_OT_select_all_toggle(wmOperatorType *ot)
ot->poll = graphop_visible_keyframes_poll;
/* flags */
- ot->flag = OPTYPE_REGISTER /*|OPTYPE_UNDO*/;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
ot->prop = RNA_def_boolean(ot->srna, "invert", 0, "Invert", "");
@@ -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;
}
@@ -266,7 +272,8 @@ static void borderselect_graphkeys(
for (ale = anim_data.first; ale; ale = ale->next) {
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
FCurve *fcu = (FCurve *)ale->key_data;
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag);
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
/* apply NLA mapping to all the keyframes, since it's easier than trying to
* guess when a callback might use something different
@@ -276,8 +283,8 @@ static void borderselect_graphkeys(
scaled_rectf.xmin = rectf.xmin;
scaled_rectf.xmax = rectf.xmax;
- scaled_rectf.ymin = rectf.ymin / unit_scale;
- scaled_rectf.ymax = rectf.ymax / unit_scale;
+ scaled_rectf.ymin = rectf.ymin / unit_scale - offset;
+ scaled_rectf.ymax = rectf.ymax / unit_scale - offset;
/* set horizontal range (if applicable)
* NOTE: these values are only used for x-range and y-range but not region
@@ -390,7 +397,7 @@ void GRAPH_OT_select_border(wmOperatorType *ot)
ot->poll = graphop_visible_keyframes_poll;
/* flags */
- ot->flag = OPTYPE_REGISTER /*|OPTYPE_UNDO*/;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* rna */
WM_operator_properties_gesture_border(ot, true);
@@ -485,6 +492,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)
@@ -662,7 +744,7 @@ void GRAPH_OT_select_column(wmOperatorType *ot)
ot->poll = graphop_visible_keyframes_poll;
/* flags */
- ot->flag = OPTYPE_REGISTER /*|OPTYPE_UNDO*/;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
/* props */
ot->prop = RNA_def_enum(ot->srna, "mode", prop_column_select_types, 0, "Mode", "");
@@ -720,7 +802,7 @@ void GRAPH_OT_select_linked(wmOperatorType *ot)
ot->poll = graphop_visible_keyframes_poll;
/* flags */
- ot->flag = OPTYPE_REGISTER /*|OPTYPE_UNDO*/;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Select More/Less Operators *********************** */
@@ -798,7 +880,7 @@ void GRAPH_OT_select_more(wmOperatorType *ot)
ot->poll = graphop_visible_keyframes_poll;
/* flags */
- ot->flag = OPTYPE_REGISTER /*|OPTYPE_UNDO*/;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ----------------- */
@@ -832,7 +914,7 @@ void GRAPH_OT_select_less(wmOperatorType *ot)
ot->poll = graphop_visible_keyframes_poll;
/* flags */
- ot->flag = OPTYPE_REGISTER /*|OPTYPE_UNDO*/;
+ ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
}
/* ******************** Select Left/Right Operator ************************* */
@@ -1008,6 +1090,8 @@ typedef struct tNearestVertInfo {
short hpoint; /* the handle index that we hit (eHandleIndex) */
short sel; /* whether the handle is selected or not */
int dist; /* distance from mouse to vert */
+
+ eAnim_ChannelType ctype; /* type of animation channel this FCurve comes from */
} tNearestVertInfo;
/* Tags for the type of graph vert that we have */
@@ -1028,15 +1112,15 @@ typedef enum eGraphVertIndex {
static bool fcurve_handle_sel_check(SpaceIpo *sipo, BezTriple *bezt)
{
if (sipo->flag & SIPO_NOHANDLES) return 0;
- if ((sipo->flag & SIPO_SELVHANDLESONLY) && BEZSELECTED(bezt) == 0) return 0;
+ if ((sipo->flag & SIPO_SELVHANDLESONLY) && BEZT_ISSEL_ANY(bezt) == 0) return 0;
return 1;
}
/* check if the given vertex is within bounds or not */
// TODO: should we return if we hit something?
static void nearest_fcurve_vert_store(
- ListBase *matches, View2D *v2d, FCurve *fcu,
- BezTriple *bezt, FPoint *fpt, short hpoint, const int mval[2], float unit_scale)
+ ListBase *matches, View2D *v2d, FCurve *fcu, eAnim_ChannelType ctype,
+ BezTriple *bezt, FPoint *fpt, short hpoint, const int mval[2], float unit_scale, float offset)
{
/* Keyframes or Samples? */
if (bezt) {
@@ -1048,7 +1132,7 @@ static void nearest_fcurve_vert_store(
* 'vec' matrix
*/
if (UI_view2d_view_to_region_clip(v2d,
- bezt->vec[hpoint + 1][0], bezt->vec[hpoint + 1][1] * unit_scale,
+ bezt->vec[hpoint + 1][0], (bezt->vec[hpoint + 1][1] + offset) * unit_scale,
&screen_co[0], &screen_co[1]) &&
/* check if distance from mouse cursor to vert in screen space is within tolerance */
((dist = len_v2v2_int(mval, screen_co)) <= GVERTSEL_TOL))
@@ -1059,7 +1143,7 @@ static void nearest_fcurve_vert_store(
/* if there is already a point for the F-Curve, check if this point is closer than that was */
if ((nvi) && (nvi->fcu == fcu)) {
/* replace if we are closer, or if equal and that one wasn't selected but we are... */
- if ((nvi->dist > dist) || ((nvi->sel == 0) && BEZSELECTED(bezt)))
+ if ((nvi->dist > dist) || ((nvi->sel == 0) && BEZT_ISSEL_ANY(bezt)))
replace = 1;
}
/* add new if not replacing... */
@@ -1068,11 +1152,13 @@ static void nearest_fcurve_vert_store(
/* store values */
nvi->fcu = fcu;
+ nvi->ctype = ctype;
+
nvi->bezt = bezt;
nvi->hpoint = hpoint;
nvi->dist = dist;
- nvi->sel = BEZSELECTED(bezt); // XXX... should this use the individual verts instead?
+ nvi->sel = BEZT_ISSEL_ANY(bezt); // XXX... should this use the individual verts instead?
/* add to list of matches if appropriate... */
if (replace == 0)
@@ -1108,30 +1194,31 @@ static void get_nearest_fcurve_verts_list(bAnimContext *ac, const int mval[2], L
for (ale = anim_data.first; ale; ale = ale->next) {
FCurve *fcu = (FCurve *)ale->key_data;
AnimData *adt = ANIM_nla_mapping_get(ac, ale);
- float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag);
-
+ float offset;
+ float unit_scale = ANIM_unit_mapping_get_factor(ac->scene, ale->id, fcu, mapping_flag, &offset);
+
/* apply NLA mapping to all the keyframes */
if (adt)
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
-
+
if (fcu->bezt) {
BezTriple *bezt1 = fcu->bezt, *prevbezt = NULL;
int i;
for (i = 0; i < fcu->totvert; i++, prevbezt = bezt1, bezt1++) {
/* keyframe */
- nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_KEY, mval, unit_scale);
+ nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_KEY, mval, unit_scale, offset);
/* handles - only do them if they're visible */
if (fcurve_handle_sel_check(sipo, bezt1) && (fcu->totvert > 1)) {
/* first handle only visible if previous segment had handles */
if ((!prevbezt && (bezt1->ipo == BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo == BEZT_IPO_BEZ))) {
- nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_LEFT, mval, unit_scale);
+ nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_LEFT, mval, unit_scale, offset);
}
/* second handle only visible if this segment is bezier */
if (bezt1->ipo == BEZT_IPO_BEZ) {
- nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_RIGHT, mval, unit_scale);
+ nearest_fcurve_vert_store(matches, v2d, fcu, ale->type, bezt1, NULL, NEAREST_HANDLE_RIGHT, mval, unit_scale, offset);
}
}
}
@@ -1251,11 +1338,11 @@ static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_m
if (select_mode == SELECT_INVERT) {
/* keyframe - invert select of all */
if (nvi->hpoint == NEAREST_HANDLE_KEY) {
- if (BEZSELECTED(bezt)) {
- BEZ_DESEL(bezt);
+ if (BEZT_ISSEL_ANY(bezt)) {
+ BEZT_DESEL_ALL(bezt);
}
else {
- BEZ_SEL(bezt);
+ BEZT_SEL_ALL(bezt);
}
}
@@ -1272,7 +1359,7 @@ static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_m
else {
/* if the keyframe was clicked on, select all verts of given beztriple */
if (nvi->hpoint == NEAREST_HANDLE_KEY) {
- BEZ_SEL(bezt);
+ BEZT_SEL_ALL(bezt);
}
/* otherwise, select the handle that applied */
else if (nvi->hpoint == NEAREST_HANDLE_LEFT)
@@ -1306,7 +1393,7 @@ static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_m
/* take selection status from item that got hit, to prevent flip/flop on channel
* selection status when shift-selecting (i.e. "SELECT_INVERT") points
*/
- if (BEZSELECTED(bezt))
+ if (BEZT_ISSEL_ANY(bezt))
nvi->fcu->flag |= FCURVE_SELECTED;
else
nvi->fcu->flag &= ~FCURVE_SELECTED;
@@ -1324,7 +1411,7 @@ static void mouse_graph_keys(bAnimContext *ac, const int mval[2], short select_m
/* needs to be called with (sipo->flag & SIPO_SELCUVERTSONLY) otherwise the active flag won't be set [#26452] */
if (nvi->fcu->flag & FCURVE_SELECTED) {
int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
- ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, ANIMTYPE_FCURVE);
+ ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, nvi->ctype);
}
/* free temp sample data for filtering */