2011-02-23 10:52:22 +00:00
|
|
|
/*
|
2009-01-26 23:18:27 +00:00
|
|
|
* ***** 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,
|
2010-02-12 13:34:04 +00:00
|
|
|
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
2009-01-26 23:18:27 +00:00
|
|
|
*
|
|
|
|
* The Original Code is Copyright (C) 2008 Blender Foundation
|
|
|
|
*
|
|
|
|
* Contributor(s): Joshua Leung
|
|
|
|
*
|
|
|
|
* ***** END GPL LICENSE BLOCK *****
|
|
|
|
*/
|
|
|
|
|
2011-02-27 20:29:51 +00:00
|
|
|
/** \file blender/editors/space_graph/graph_select.c
|
|
|
|
* \ingroup spgraph
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2009-01-26 23:18:27 +00:00
|
|
|
#include <math.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <float.h>
|
|
|
|
|
|
|
|
#include "MEM_guardedalloc.h"
|
|
|
|
|
|
|
|
#include "BLI_blenlib.h"
|
2009-11-10 20:43:45 +00:00
|
|
|
#include "BLI_math.h"
|
2011-01-07 18:36:47 +00:00
|
|
|
#include "BLI_utildefines.h"
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
#include "DNA_anim_types.h"
|
|
|
|
#include "DNA_object_types.h"
|
|
|
|
#include "DNA_screen_types.h"
|
|
|
|
#include "DNA_scene_types.h"
|
|
|
|
#include "DNA_space_types.h"
|
|
|
|
|
|
|
|
#include "RNA_access.h"
|
|
|
|
#include "RNA_define.h"
|
|
|
|
|
|
|
|
#include "BKE_fcurve.h"
|
2009-06-23 13:25:31 +00:00
|
|
|
#include "BKE_nla.h"
|
2009-01-26 23:18:27 +00:00
|
|
|
#include "BKE_context.h"
|
|
|
|
|
|
|
|
#include "UI_view2d.h"
|
|
|
|
|
|
|
|
#include "ED_anim_api.h"
|
|
|
|
#include "ED_keyframes_edit.h"
|
2009-05-08 12:51:36 +00:00
|
|
|
#include "ED_markers.h"
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
#include "WM_api.h"
|
|
|
|
#include "WM_types.h"
|
|
|
|
|
2009-02-03 12:04:05 +00:00
|
|
|
#include "graph_intern.h"
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* ************************************************************************** */
|
|
|
|
/* KEYFRAMES STUFF */
|
|
|
|
|
|
|
|
/* ******************** Deselect All Operator ***************************** */
|
|
|
|
/* This operator works in one of three ways:
|
|
|
|
* 1) (de)select all (AKEY) - test if select all or deselect all
|
|
|
|
* 2) invert all (CTRL-IKEY) - invert selection of all keyframes
|
|
|
|
* 3) (de)select all - no testing is done; only for use internal tools as normal function...
|
|
|
|
*/
|
|
|
|
|
2009-04-08 01:07:46 +00:00
|
|
|
/* Deselects keyframes in the Graph Editor
|
2009-01-26 23:18:27 +00:00
|
|
|
* - This is called by the deselect all operator, as well as other ones!
|
|
|
|
*
|
|
|
|
* - test: check if select or deselect all
|
|
|
|
* - sel: how to select keyframes
|
|
|
|
* 0 = deselect
|
|
|
|
* 1 = select
|
|
|
|
* 2 = invert
|
2011-11-15 12:02:44 +00:00
|
|
|
* - do_channels: whether to affect selection status of channels
|
2009-01-26 23:18:27 +00:00
|
|
|
*/
|
2011-11-15 12:02:44 +00:00
|
|
|
static void deselect_graph_keys (bAnimContext *ac, short test, short sel, short do_channels)
|
2009-01-26 23:18:27 +00:00
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
2011-06-21 01:41:39 +00:00
|
|
|
SpaceIpo *sipo= (SpaceIpo *)ac->sl;
|
2011-03-05 10:29:10 +00:00
|
|
|
KeyframeEditData ked= {{NULL}};
|
2010-04-02 12:02:39 +00:00
|
|
|
KeyframeEditFunc test_cb, sel_cb;
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* determine type-based settings */
|
Animation Channel Filtering Refactor - Part 3 (Visibility Flag Split)
* This (big) commit is aimed at cleaning up the filtering flags used
by the animation channel filtering code. The list of filtering flags
has been growing a bit "organically" since it's humble origins for use
in the Action Editor some 3 years (IIRC) ago now during a weekend
hackathon. Obviously, some things have ended up tacked on, while
others have been the product of other flag options. Nevertheless, it
was time for a bit of a spring clean!
* Most notably, one area where the system outgrown its original design
for the Action Editor was in terms of the "visibility" filtering flag
it was using. While in the Action Editor the concept of what channels
to include was strictly dictated by whether the channel hierarchy
showed it, in the Graph Editor this is not always the case. In other
words, there was a difference between the data the channels
represented being visible and the channels for that data being visible
in the hierarchy.
Long story short: this lead to bug report [#27076] (and many like it),
where if you selected an F-Curve, then collapsed the Group it was in,
then even after selecting another F-Curve in another Group, the
original F-Curve's properties would still be shown in the Properties
Region. The good news is that this commit fixes this issue right away!
* More good news will follow, as I start checking on the flag usage of
other tools, but I'm committing this first so that we have a stable
reference (of code similar to the old buggy stuff) on which we can
fall back to later to find bugs (should they pop up).
Anyways, back to the trenches!
2011-06-22 11:41:26 +00:00
|
|
|
filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* filter data */
|
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
/* init BezTriple looping data */
|
|
|
|
test_cb= ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
|
|
|
|
|
|
|
|
/* See if we should be selecting or deselecting */
|
|
|
|
if (test) {
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
2010-04-02 12:02:39 +00:00
|
|
|
if (ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, test_cb, NULL)) {
|
2009-01-27 05:04:23 +00:00
|
|
|
sel= SELECT_SUBTRACT;
|
|
|
|
break;
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* convert sel to selectmode, and use that to get editor */
|
|
|
|
sel_cb= ANIM_editkeyframes_select(sel);
|
|
|
|
|
|
|
|
/* Now set the flags */
|
2009-02-09 10:33:05 +00:00
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
FCurve *fcu= (FCurve *)ale->key_data;
|
|
|
|
|
|
|
|
/* Keyframes First */
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL);
|
2009-02-09 10:33:05 +00:00
|
|
|
|
2011-11-15 12:02:44 +00:00
|
|
|
/* affect channel selection status? */
|
|
|
|
if (do_channels) {
|
|
|
|
/* only change selection of channel when the visibility of keyframes doesn't depend on this */
|
|
|
|
if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
|
|
|
|
/* deactivate the F-Curve, and deselect if deselecting keyframes.
|
|
|
|
* otherwise select the F-Curve too since we've selected all the keyframes
|
|
|
|
*/
|
|
|
|
if (sel == SELECT_SUBTRACT)
|
|
|
|
fcu->flag &= ~FCURVE_SELECTED;
|
|
|
|
else
|
|
|
|
fcu->flag |= FCURVE_SELECTED;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* always deactivate all F-Curves if we perform batch ops for selection */
|
|
|
|
fcu->flag &= ~FCURVE_ACTIVE;
|
2010-01-22 23:51:31 +00:00
|
|
|
}
|
2009-02-09 10:33:05 +00:00
|
|
|
}
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* Cleanup */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int graphkeys_deselectall_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* 'standard' behaviour - check if selected, then apply relevant selection */
|
|
|
|
if (RNA_boolean_get(op->ptr, "invert"))
|
2011-11-15 12:02:44 +00:00
|
|
|
deselect_graph_keys(&ac, 0, SELECT_INVERT, TRUE);
|
2009-01-26 23:18:27 +00:00
|
|
|
else
|
2011-11-15 12:02:44 +00:00
|
|
|
deselect_graph_keys(&ac, 1, SELECT_ADD, TRUE);
|
2009-01-26 23:18:27 +00:00
|
|
|
|
2009-04-10 03:34:20 +00:00
|
|
|
/* set notifier that things have changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL);
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-06-22 04:23:06 +00:00
|
|
|
void GRAPH_OT_select_all_toggle (wmOperatorType *ot)
|
2009-01-26 23:18:27 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select All";
|
2009-06-22 04:23:06 +00:00
|
|
|
ot->idname= "GRAPH_OT_select_all_toggle";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Toggle selection of all keyframes";
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= graphkeys_deselectall_exec;
|
2009-07-02 01:01:18 +00:00
|
|
|
ot->poll= graphop_visible_keyframes_poll;
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
|
|
|
|
|
|
|
|
/* props */
|
2010-02-07 23:39:44 +00:00
|
|
|
ot->prop= RNA_def_boolean(ot->srna, "invert", 0, "Invert", "");
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************** Border Select Operator **************************** */
|
|
|
|
/* This operator currently works in one of three ways:
|
2009-01-27 11:09:30 +00:00
|
|
|
* -> BKEY - 1) all keyframes within region are selected (validation with BEZT_OK_REGION)
|
2009-01-26 23:18:27 +00:00
|
|
|
* -> ALT-BKEY - depending on which axis of the region was larger...
|
2009-01-27 11:09:30 +00:00
|
|
|
* -> 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 (validation with BEZT_OK_VALUERANGE)
|
2009-01-26 23:18:27 +00:00
|
|
|
*/
|
|
|
|
|
2009-01-27 11:09:30 +00:00
|
|
|
/* Borderselect only selects keyframes now, as overshooting handles often get caught too,
|
2010-04-05 03:37:28 +00:00
|
|
|
* which means that they may be inadvertantly 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).
|
2009-01-27 11:09:30 +00:00
|
|
|
*/
|
2010-04-05 03:37:28 +00:00
|
|
|
static void borderselect_graphkeys (bAnimContext *ac, rcti rect, short mode, short selectmode, short incl_handles)
|
2009-01-26 23:18:27 +00:00
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
2011-06-21 01:41:39 +00:00
|
|
|
SpaceIpo *sipo= (SpaceIpo *)ac->sl;
|
2010-04-02 12:02:39 +00:00
|
|
|
KeyframeEditData ked;
|
|
|
|
KeyframeEditFunc ok_cb, select_cb;
|
2009-01-26 23:18:27 +00:00
|
|
|
View2D *v2d= &ac->ar->v2d;
|
|
|
|
rctf rectf;
|
|
|
|
|
|
|
|
/* convert mouse coordinates to frame ranges and channel coordinates corrected for view pan/zoom */
|
2009-01-27 11:09:30 +00:00
|
|
|
UI_view2d_region_to_view(v2d, rect.xmin, rect.ymin, &rectf.xmin, &rectf.ymin);
|
|
|
|
UI_view2d_region_to_view(v2d, rect.xmax, rect.ymax, &rectf.xmax, &rectf.ymax);
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* filter data */
|
Animation Channel Filtering Refactor - Part 3 (Visibility Flag Split)
* This (big) commit is aimed at cleaning up the filtering flags used
by the animation channel filtering code. The list of filtering flags
has been growing a bit "organically" since it's humble origins for use
in the Action Editor some 3 years (IIRC) ago now during a weekend
hackathon. Obviously, some things have ended up tacked on, while
others have been the product of other flag options. Nevertheless, it
was time for a bit of a spring clean!
* Most notably, one area where the system outgrown its original design
for the Action Editor was in terms of the "visibility" filtering flag
it was using. While in the Action Editor the concept of what channels
to include was strictly dictated by whether the channel hierarchy
showed it, in the Graph Editor this is not always the case. In other
words, there was a difference between the data the channels
represented being visible and the channels for that data being visible
in the hierarchy.
Long story short: this lead to bug report [#27076] (and many like it),
where if you selected an F-Curve, then collapsed the Group it was in,
then even after selecting another F-Curve in another Group, the
original F-Curve's properties would still be shown in the Properties
Region. The good news is that this commit fixes this issue right away!
* More good news will follow, as I start checking on the flag usage of
other tools, but I'm committing this first so that we have a stable
reference (of code similar to the old buggy stuff) on which we can
fall back to later to find bugs (should they pop up).
Anyways, back to the trenches!
2011-06-22 11:41:26 +00:00
|
|
|
filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
|
2009-01-26 23:18:27 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
/* get beztriple editing/validation funcs */
|
|
|
|
select_cb= ANIM_editkeyframes_select(selectmode);
|
2009-01-27 11:09:30 +00:00
|
|
|
ok_cb= ANIM_editkeyframes_ok(mode);
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* init editing data */
|
2010-04-02 12:02:39 +00:00
|
|
|
memset(&ked, 0, sizeof(KeyframeEditData));
|
|
|
|
ked.data= &rectf;
|
2009-01-26 23:18:27 +00:00
|
|
|
|
2010-04-05 03:37:28 +00:00
|
|
|
/* treat handles separately? */
|
|
|
|
if (incl_handles)
|
|
|
|
ked.iterflags |= KEYFRAME_ITER_INCL_HANDLES;
|
|
|
|
|
2009-01-26 23:18:27 +00:00
|
|
|
/* loop over data, doing border select */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
2009-06-23 13:25:31 +00:00
|
|
|
AnimData *adt= ANIM_nla_mapping_get(ac, ale);
|
2009-09-11 09:09:54 +00:00
|
|
|
FCurve *fcu= (FCurve *)ale->key_data;
|
2010-01-19 19:53:50 +00:00
|
|
|
|
2010-01-26 03:16:14 +00:00
|
|
|
/* apply unit corrections */
|
2010-01-26 09:25:32 +00:00
|
|
|
ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, ANIM_UNITCONV_ONLYKEYS);
|
2010-01-26 03:16:14 +00:00
|
|
|
|
2010-01-19 19:53:50 +00:00
|
|
|
/* apply NLA mapping to all the keyframes, since it's easier than trying to
|
|
|
|
* guess when a callback might use something different
|
|
|
|
*/
|
2010-01-19 15:12:14 +00:00
|
|
|
if (adt)
|
2011-03-09 15:04:09 +00:00
|
|
|
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, incl_handles==0);
|
2010-01-19 19:53:50 +00:00
|
|
|
|
|
|
|
/* set horizontal range (if applicable)
|
|
|
|
* NOTE: these values are only used for x-range and y-range but not region
|
2010-04-02 12:02:39 +00:00
|
|
|
* (which uses ked.data, i.e. rectf)
|
2010-01-19 19:53:50 +00:00
|
|
|
*/
|
2009-01-27 11:09:30 +00:00
|
|
|
if (mode != BEZT_OK_VALUERANGE) {
|
2010-04-02 12:02:39 +00:00
|
|
|
ked.f1= rectf.xmin;
|
|
|
|
ked.f2= rectf.xmax;
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
2009-01-27 11:14:02 +00:00
|
|
|
else {
|
2010-04-02 12:02:39 +00:00
|
|
|
ked.f1= rectf.ymin;
|
|
|
|
ked.f2= rectf.ymax;
|
2009-01-27 11:14:02 +00:00
|
|
|
}
|
2009-01-26 23:18:27 +00:00
|
|
|
|
2010-01-19 19:53:50 +00:00
|
|
|
/* firstly, check if any keyframes will be hit by this */
|
2010-04-02 12:02:39 +00:00
|
|
|
if (ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, ok_cb, NULL)) {
|
2010-01-19 19:53:50 +00:00
|
|
|
/* select keyframes that are in the appropriate places */
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, fcu, ok_cb, select_cb, NULL);
|
2010-01-19 19:53:50 +00:00
|
|
|
|
2010-01-22 23:51:31 +00:00
|
|
|
/* only change selection of channel when the visibility of keyframes doesn't depend on this */
|
|
|
|
if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
|
|
|
|
/* select the curve too now that curve will be touched */
|
|
|
|
if (selectmode == SELECT_ADD)
|
|
|
|
fcu->flag |= FCURVE_SELECTED;
|
|
|
|
}
|
2009-09-25 10:52:29 +00:00
|
|
|
}
|
2010-01-19 19:53:50 +00:00
|
|
|
|
2010-01-19 15:12:14 +00:00
|
|
|
/* un-apply NLA mapping from all the keyframes */
|
|
|
|
if (adt)
|
2011-03-09 15:04:09 +00:00
|
|
|
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, incl_handles==0);
|
2010-01-26 03:16:14 +00:00
|
|
|
|
|
|
|
/* unapply unit corrections */
|
2010-01-26 09:25:32 +00:00
|
|
|
ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, ANIM_UNITCONV_RESTORE|ANIM_UNITCONV_ONLYKEYS);
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* cleanup */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int graphkeys_borderselect_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
rcti rect;
|
|
|
|
short mode=0, selectmode=0;
|
2010-04-05 03:37:28 +00:00
|
|
|
short incl_handles;
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
2010-04-05 03:37:28 +00:00
|
|
|
|
|
|
|
/* get select mode
|
|
|
|
* - 'gesture_mode' from the operator specifies how to select
|
|
|
|
* - 'include_handles' from the operator specifies whether to include handles in the selection
|
|
|
|
*/
|
2010-01-22 23:51:31 +00:00
|
|
|
if (RNA_int_get(op->ptr, "gesture_mode")==GESTURE_MODAL_SELECT)
|
2009-11-06 22:51:08 +00:00
|
|
|
selectmode= SELECT_ADD;
|
|
|
|
else
|
|
|
|
selectmode= SELECT_SUBTRACT;
|
2010-04-05 03:37:28 +00:00
|
|
|
|
|
|
|
incl_handles = RNA_boolean_get(op->ptr, "include_handles");
|
|
|
|
|
2009-01-26 23:18:27 +00:00
|
|
|
/* get settings from operator */
|
|
|
|
rect.xmin= RNA_int_get(op->ptr, "xmin");
|
|
|
|
rect.ymin= RNA_int_get(op->ptr, "ymin");
|
|
|
|
rect.xmax= RNA_int_get(op->ptr, "xmax");
|
|
|
|
rect.ymax= RNA_int_get(op->ptr, "ymax");
|
|
|
|
|
|
|
|
/* selection 'mode' depends on whether borderselect region only matters on one axis */
|
|
|
|
if (RNA_boolean_get(op->ptr, "axis_range")) {
|
|
|
|
/* 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 different rect size
|
|
|
|
* - the frame-range select option is favoured over the channel one (x over y), as frame-range one is often
|
|
|
|
* used for tweaking timing when "blocking", while channels is not that useful...
|
|
|
|
*/
|
|
|
|
if ((rect.xmax - rect.xmin) >= (rect.ymax - rect.ymin))
|
2009-01-27 11:09:30 +00:00
|
|
|
mode= BEZT_OK_FRAMERANGE;
|
|
|
|
else
|
|
|
|
mode= BEZT_OK_VALUERANGE;
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
else
|
2009-01-27 11:09:30 +00:00
|
|
|
mode= BEZT_OK_REGION;
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* apply borderselect action */
|
2010-04-05 03:37:28 +00:00
|
|
|
borderselect_graphkeys(&ac, rect, mode, selectmode, incl_handles);
|
2009-01-26 23:18:27 +00:00
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* send notifier that keyframe selection has changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL);
|
2009-07-10 10:48:25 +00:00
|
|
|
|
2009-01-26 23:18:27 +00:00
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-06-22 04:23:06 +00:00
|
|
|
void GRAPH_OT_select_border(wmOperatorType *ot)
|
2009-01-26 23:18:27 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Border Select";
|
2009-06-22 04:23:06 +00:00
|
|
|
ot->idname= "GRAPH_OT_select_border";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Select all keyframes within the specified region";
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= WM_border_select_invoke;
|
|
|
|
ot->exec= graphkeys_borderselect_exec;
|
|
|
|
ot->modal= WM_border_select_modal;
|
2011-06-06 11:04:54 +00:00
|
|
|
ot->cancel= WM_border_select_cancel;
|
2009-01-26 23:18:27 +00:00
|
|
|
|
2009-07-02 01:01:18 +00:00
|
|
|
ot->poll= graphop_visible_keyframes_poll;
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
|
|
|
|
|
|
|
|
/* rna */
|
2009-11-06 22:51:08 +00:00
|
|
|
WM_operator_properties_gesture_border(ot, FALSE);
|
2009-01-26 23:18:27 +00:00
|
|
|
|
2010-02-07 23:39:44 +00:00
|
|
|
ot->prop= RNA_def_boolean(ot->srna, "axis_range", 0, "Axis Range", "");
|
2010-04-05 03:37:28 +00:00
|
|
|
RNA_def_boolean(ot->srna, "include_handles", 0, "Include Handles", "Are handles tested individually against the selection criteria");
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************** Column Select Operator **************************** */
|
|
|
|
/* This operator works in one of four ways:
|
|
|
|
* - 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)
|
|
|
|
* - 3) select all keyframes in the same frame as a selected markers (SHIFT-KKEY)
|
|
|
|
* - 4) select all keyframes that occur between selected markers (ALT-KKEY)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* defines for column-select mode */
|
2009-01-27 05:04:23 +00:00
|
|
|
static EnumPropertyItem prop_column_select_types[] = {
|
2009-06-16 00:52:21 +00:00
|
|
|
{GRAPHKEYS_COLUMNSEL_KEYS, "KEYS", 0, "On Selected Keyframes", ""},
|
|
|
|
{GRAPHKEYS_COLUMNSEL_CFRA, "CFRA", 0, "On Current Frame", ""},
|
|
|
|
{GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN, "MARKERS_COLUMN", 0, "On Selected Markers", ""},
|
|
|
|
{GRAPHKEYS_COLUMNSEL_MARKERS_BETWEEN, "MARKERS_BETWEEN", 0, "Between Min/Max Selected Markers", ""},
|
|
|
|
{0, NULL, 0, NULL, NULL}
|
2009-01-26 23:18:27 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
/* Selects all visible keyframes between the specified markers */
|
|
|
|
static void markers_selectkeys_between (bAnimContext *ac)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
2010-04-02 12:02:39 +00:00
|
|
|
KeyframeEditFunc ok_cb, select_cb;
|
|
|
|
KeyframeEditData ked;
|
2009-01-26 23:18:27 +00:00
|
|
|
float min, max;
|
|
|
|
|
|
|
|
/* get extreme markers */
|
2009-05-09 02:37:12 +00:00
|
|
|
ED_markers_get_minmax(ac->markers, 1, &min, &max);
|
2009-01-26 23:18:27 +00:00
|
|
|
min -= 0.5f;
|
|
|
|
max += 0.5f;
|
|
|
|
|
|
|
|
/* get editing funcs + data */
|
2009-05-09 02:37:12 +00:00
|
|
|
ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
|
2009-01-26 23:18:27 +00:00
|
|
|
select_cb= ANIM_editkeyframes_select(SELECT_ADD);
|
2009-05-09 02:37:12 +00:00
|
|
|
|
2010-04-02 12:02:39 +00:00
|
|
|
memset(&ked, 0, sizeof(KeyframeEditData));
|
|
|
|
ked.f1= min;
|
|
|
|
ked.f2= max;
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* filter data */
|
Animation Channel Filtering Refactor - Part 3 (Visibility Flag Split)
* This (big) commit is aimed at cleaning up the filtering flags used
by the animation channel filtering code. The list of filtering flags
has been growing a bit "organically" since it's humble origins for use
in the Action Editor some 3 years (IIRC) ago now during a weekend
hackathon. Obviously, some things have ended up tacked on, while
others have been the product of other flag options. Nevertheless, it
was time for a bit of a spring clean!
* Most notably, one area where the system outgrown its original design
for the Action Editor was in terms of the "visibility" filtering flag
it was using. While in the Action Editor the concept of what channels
to include was strictly dictated by whether the channel hierarchy
showed it, in the Graph Editor this is not always the case. In other
words, there was a difference between the data the channels
represented being visible and the channels for that data being visible
in the hierarchy.
Long story short: this lead to bug report [#27076] (and many like it),
where if you selected an F-Curve, then collapsed the Group it was in,
then even after selecting another F-Curve in another Group, the
original F-Curve's properties would still be shown in the Properties
Region. The good news is that this commit fixes this issue right away!
* More good news will follow, as I start checking on the flag usage of
other tools, but I'm committing this first so that we have a stable
reference (of code similar to the old buggy stuff) on which we can
fall back to later to find bugs (should they pop up).
Anyways, back to the trenches!
2011-06-22 11:41:26 +00:00
|
|
|
filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
|
2009-01-26 23:18:27 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
/* select keys in-between */
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
2009-06-23 13:25:31 +00:00
|
|
|
AnimData *adt= ANIM_nla_mapping_get(ac, ale);
|
2009-01-26 23:18:27 +00:00
|
|
|
|
2009-06-23 13:25:31 +00:00
|
|
|
if (adt) {
|
2010-01-15 10:34:39 +00:00
|
|
|
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 1);
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
|
2010-01-15 10:34:39 +00:00
|
|
|
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
else {
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cleanup */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Selects all visible keyframes in the same frames as the specified elements */
|
|
|
|
static void columnselect_graph_keys (bAnimContext *ac, short mode)
|
|
|
|
{
|
|
|
|
ListBase anim_data= {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
Scene *scene= ac->scene;
|
|
|
|
CfraElem *ce;
|
2010-04-02 12:02:39 +00:00
|
|
|
KeyframeEditFunc select_cb, ok_cb;
|
|
|
|
KeyframeEditData ked;
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* initialise keyframe editing data */
|
2010-04-02 12:02:39 +00:00
|
|
|
memset(&ked, 0, sizeof(KeyframeEditData));
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* build list of columns */
|
|
|
|
switch (mode) {
|
2009-01-27 05:04:23 +00:00
|
|
|
case GRAPHKEYS_COLUMNSEL_KEYS: /* list of selected keys */
|
Animation Channel Filtering Refactor - Part 3 (Visibility Flag Split)
* This (big) commit is aimed at cleaning up the filtering flags used
by the animation channel filtering code. The list of filtering flags
has been growing a bit "organically" since it's humble origins for use
in the Action Editor some 3 years (IIRC) ago now during a weekend
hackathon. Obviously, some things have ended up tacked on, while
others have been the product of other flag options. Nevertheless, it
was time for a bit of a spring clean!
* Most notably, one area where the system outgrown its original design
for the Action Editor was in terms of the "visibility" filtering flag
it was using. While in the Action Editor the concept of what channels
to include was strictly dictated by whether the channel hierarchy
showed it, in the Graph Editor this is not always the case. In other
words, there was a difference between the data the channels
represented being visible and the channels for that data being visible
in the hierarchy.
Long story short: this lead to bug report [#27076] (and many like it),
where if you selected an F-Curve, then collapsed the Group it was in,
then even after selecting another F-Curve in another Group, the
original F-Curve's properties would still be shown in the Properties
Region. The good news is that this commit fixes this issue right away!
* More good news will follow, as I start checking on the flag usage of
other tools, but I'm committing this first so that we have a stable
reference (of code similar to the old buggy stuff) on which we can
fall back to later to find bugs (should they pop up).
Anyways, back to the trenches!
2011-06-22 11:41:26 +00:00
|
|
|
filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
|
2009-01-27 05:04:23 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next)
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, bezt_to_cfraelem, NULL);
|
2009-01-27 05:04:23 +00:00
|
|
|
|
2009-01-26 23:18:27 +00:00
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
break;
|
|
|
|
|
2009-01-27 05:04:23 +00:00
|
|
|
case GRAPHKEYS_COLUMNSEL_CFRA: /* current frame */
|
2009-01-26 23:18:27 +00:00
|
|
|
/* make a single CfraElem for storing this */
|
|
|
|
ce= MEM_callocN(sizeof(CfraElem), "cfraElem");
|
2010-04-02 12:02:39 +00:00
|
|
|
BLI_addtail(&ked.list, ce);
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
ce->cfra= (float)CFRA;
|
|
|
|
break;
|
|
|
|
|
2009-01-27 05:04:23 +00:00
|
|
|
case GRAPHKEYS_COLUMNSEL_MARKERS_COLUMN: /* list of selected markers */
|
2011-03-31 01:37:42 +00:00
|
|
|
ED_markers_make_cfra_list(ac->markers, &ked.list, SELECT);
|
2009-01-26 23:18:27 +00:00
|
|
|
break;
|
|
|
|
|
|
|
|
default: /* invalid option */
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* set up BezTriple edit callbacks */
|
|
|
|
select_cb= ANIM_editkeyframes_select(SELECT_ADD);
|
|
|
|
ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAME);
|
|
|
|
|
|
|
|
/* loop through all of the keys and select additional keyframes
|
|
|
|
* based on the keys found to be selected above
|
|
|
|
*/
|
Animation Channel Filtering Refactor - Part 3 (Visibility Flag Split)
* This (big) commit is aimed at cleaning up the filtering flags used
by the animation channel filtering code. The list of filtering flags
has been growing a bit "organically" since it's humble origins for use
in the Action Editor some 3 years (IIRC) ago now during a weekend
hackathon. Obviously, some things have ended up tacked on, while
others have been the product of other flag options. Nevertheless, it
was time for a bit of a spring clean!
* Most notably, one area where the system outgrown its original design
for the Action Editor was in terms of the "visibility" filtering flag
it was using. While in the Action Editor the concept of what channels
to include was strictly dictated by whether the channel hierarchy
showed it, in the Graph Editor this is not always the case. In other
words, there was a difference between the data the channels
represented being visible and the channels for that data being visible
in the hierarchy.
Long story short: this lead to bug report [#27076] (and many like it),
where if you selected an F-Curve, then collapsed the Group it was in,
then even after selecting another F-Curve in another Group, the
original F-Curve's properties would still be shown in the Properties
Region. The good news is that this commit fixes this issue right away!
* More good news will follow, as I start checking on the flag usage of
other tools, but I'm committing this first so that we have a stable
reference (of code similar to the old buggy stuff) on which we can
fall back to later to find bugs (should they pop up).
Anyways, back to the trenches!
2011-06-22 11:41:26 +00:00
|
|
|
filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
|
2009-01-26 23:18:27 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
2009-06-23 13:25:31 +00:00
|
|
|
AnimData *adt= ANIM_nla_mapping_get(ac, ale);
|
2009-01-26 23:18:27 +00:00
|
|
|
|
2010-04-02 12:02:39 +00:00
|
|
|
/* loop over cfraelems (stored in the KeyframeEditData->list)
|
2009-01-26 23:18:27 +00:00
|
|
|
* - we need to do this here, as we can apply fewer NLA-mapping conversions
|
|
|
|
*/
|
2010-04-02 12:02:39 +00:00
|
|
|
for (ce= ked.list.first; ce; ce= ce->next) {
|
2009-01-26 23:18:27 +00:00
|
|
|
/* set frame for validation callback to refer to */
|
2011-04-29 06:59:18 +00:00
|
|
|
ked.f1= BKE_nla_tweakedit_remap(adt, ce->cfra, NLATIME_CONVERT_UNMAP);
|
|
|
|
|
2009-01-26 23:18:27 +00:00
|
|
|
/* select elements with frame number matching cfraelem */
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* free elements */
|
2010-04-02 12:02:39 +00:00
|
|
|
BLI_freelistN(&ked.list);
|
2009-01-26 23:18:27 +00:00
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
static int graphkeys_columnselect_exec(bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short mode;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* action to take depends on the mode */
|
|
|
|
mode= RNA_enum_get(op->ptr, "mode");
|
|
|
|
|
2009-01-27 05:04:23 +00:00
|
|
|
if (mode == GRAPHKEYS_COLUMNSEL_MARKERS_BETWEEN)
|
2009-01-26 23:18:27 +00:00
|
|
|
markers_selectkeys_between(&ac);
|
|
|
|
else
|
|
|
|
columnselect_graph_keys(&ac, mode);
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that keyframe selection has changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL);
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
2009-06-22 04:23:06 +00:00
|
|
|
void GRAPH_OT_select_column (wmOperatorType *ot)
|
2009-01-26 23:18:27 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select All";
|
2009-06-22 04:23:06 +00:00
|
|
|
ot->idname= "GRAPH_OT_select_column";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Select all keyframes on the specified frame(s)";
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= graphkeys_columnselect_exec;
|
2009-07-02 01:01:18 +00:00
|
|
|
ot->poll= graphop_visible_keyframes_poll;
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
|
|
|
|
|
|
|
|
/* props */
|
2010-02-07 23:39:44 +00:00
|
|
|
ot->prop= RNA_def_enum(ot->srna, "mode", prop_column_select_types, 0, "Mode", "");
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
|
2010-04-05 11:47:55 +00:00
|
|
|
/* ******************** Select Linked Operator *********************** */
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int graphkeys_select_linked_exec (bContext *C, wmOperator *UNUSED(op))
|
2010-04-05 11:47:55 +00:00
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
|
|
|
|
ListBase anim_data= {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
KeyframeEditFunc ok_cb = ANIM_editkeyframes_ok(BEZT_OK_SELECTED);
|
|
|
|
KeyframeEditFunc sel_cb = ANIM_editkeyframes_select(SELECT_ADD);
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* loop through all of the keys and select additional keyframes based on these */
|
Animation Channel Filtering Refactor - Part 3 (Visibility Flag Split)
* This (big) commit is aimed at cleaning up the filtering flags used
by the animation channel filtering code. The list of filtering flags
has been growing a bit "organically" since it's humble origins for use
in the Action Editor some 3 years (IIRC) ago now during a weekend
hackathon. Obviously, some things have ended up tacked on, while
others have been the product of other flag options. Nevertheless, it
was time for a bit of a spring clean!
* Most notably, one area where the system outgrown its original design
for the Action Editor was in terms of the "visibility" filtering flag
it was using. While in the Action Editor the concept of what channels
to include was strictly dictated by whether the channel hierarchy
showed it, in the Graph Editor this is not always the case. In other
words, there was a difference between the data the channels
represented being visible and the channels for that data being visible
in the hierarchy.
Long story short: this lead to bug report [#27076] (and many like it),
where if you selected an F-Curve, then collapsed the Group it was in,
then even after selecting another F-Curve in another Group, the
original F-Curve's properties would still be shown in the Properties
Region. The good news is that this commit fixes this issue right away!
* More good news will follow, as I start checking on the flag usage of
other tools, but I'm committing this first so that we have a stable
reference (of code similar to the old buggy stuff) on which we can
fall back to later to find bugs (should they pop up).
Anyways, back to the trenches!
2011-06-22 11:41:26 +00:00
|
|
|
filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
|
2010-04-05 11:47:55 +00:00
|
|
|
ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
|
|
|
|
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
FCurve *fcu= (FCurve *)ale->key_data;
|
|
|
|
|
|
|
|
/* check if anything selected? */
|
|
|
|
if (ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, ok_cb, NULL)) {
|
|
|
|
/* select every keyframe in this curve then */
|
|
|
|
ANIM_fcurve_keyframes_loop(NULL, fcu, NULL, sel_cb, NULL);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cleanup */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
|
|
|
|
/* set notifier that keyframe selection has changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL);
|
2010-04-05 11:47:55 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GRAPH_OT_select_linked (wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name = "Select Linked";
|
|
|
|
ot->idname= "GRAPH_OT_select_linked";
|
2011-09-17 10:44:16 +00:00
|
|
|
ot->description = "Select keyframes occurring in the same F-Curves as selected ones";
|
2010-04-05 11:47:55 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= graphkeys_select_linked_exec;
|
|
|
|
ot->poll= graphop_visible_keyframes_poll;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
|
|
|
|
}
|
|
|
|
|
2010-02-07 11:50:03 +00:00
|
|
|
/* ******************** Select More/Less Operators *********************** */
|
|
|
|
|
|
|
|
/* Common code to perform selection */
|
|
|
|
static void select_moreless_graph_keys (bAnimContext *ac, short mode)
|
|
|
|
{
|
|
|
|
ListBase anim_data= {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
2010-04-02 12:02:39 +00:00
|
|
|
KeyframeEditData ked;
|
|
|
|
KeyframeEditFunc build_cb;
|
2010-02-07 11:50:03 +00:00
|
|
|
|
|
|
|
|
|
|
|
/* init selmap building data */
|
|
|
|
build_cb= ANIM_editkeyframes_buildselmap(mode);
|
2010-04-02 12:02:39 +00:00
|
|
|
memset(&ked, 0, sizeof(KeyframeEditData));
|
2010-02-07 11:50:03 +00:00
|
|
|
|
|
|
|
/* loop through all of the keys and select additional keyframes based on these */
|
Animation Channel Filtering Refactor - Part 3 (Visibility Flag Split)
* This (big) commit is aimed at cleaning up the filtering flags used
by the animation channel filtering code. The list of filtering flags
has been growing a bit "organically" since it's humble origins for use
in the Action Editor some 3 years (IIRC) ago now during a weekend
hackathon. Obviously, some things have ended up tacked on, while
others have been the product of other flag options. Nevertheless, it
was time for a bit of a spring clean!
* Most notably, one area where the system outgrown its original design
for the Action Editor was in terms of the "visibility" filtering flag
it was using. While in the Action Editor the concept of what channels
to include was strictly dictated by whether the channel hierarchy
showed it, in the Graph Editor this is not always the case. In other
words, there was a difference between the data the channels
represented being visible and the channels for that data being visible
in the hierarchy.
Long story short: this lead to bug report [#27076] (and many like it),
where if you selected an F-Curve, then collapsed the Group it was in,
then even after selecting another F-Curve in another Group, the
original F-Curve's properties would still be shown in the Properties
Region. The good news is that this commit fixes this issue right away!
* More good news will follow, as I start checking on the flag usage of
other tools, but I'm committing this first so that we have a stable
reference (of code similar to the old buggy stuff) on which we can
fall back to later to find bugs (should they pop up).
Anyways, back to the trenches!
2011-06-22 11:41:26 +00:00
|
|
|
filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
|
2010-02-07 11:50:03 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
FCurve *fcu= (FCurve *)ale->key_data;
|
|
|
|
|
|
|
|
/* only continue if F-Curve has keyframes */
|
|
|
|
if (fcu->bezt == NULL)
|
|
|
|
continue;
|
|
|
|
|
|
|
|
/* build up map of whether F-Curve's keyframes should be selected or not */
|
2010-04-02 12:02:39 +00:00
|
|
|
ked.data= MEM_callocN(fcu->totvert, "selmap graphEdit");
|
|
|
|
ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, build_cb, NULL);
|
2010-02-07 11:50:03 +00:00
|
|
|
|
|
|
|
/* based on this map, adjust the selection status of the keyframes */
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, fcu, NULL, bezt_selmap_flush, NULL);
|
2010-02-07 11:50:03 +00:00
|
|
|
|
|
|
|
/* free the selmap used here */
|
2010-04-02 12:02:39 +00:00
|
|
|
MEM_freeN(ked.data);
|
|
|
|
ked.data= NULL;
|
2010-02-07 11:50:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Cleanup */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------- */
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int graphkeys_select_more_exec (bContext *C, wmOperator *UNUSED(op))
|
2010-02-07 11:50:03 +00:00
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* perform select changes */
|
|
|
|
select_moreless_graph_keys(&ac, SELMAP_MORE);
|
|
|
|
|
|
|
|
/* set notifier that keyframe selection has changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL);
|
2010-02-07 11:50:03 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GRAPH_OT_select_more (wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name = "Select More";
|
|
|
|
ot->idname= "GRAPH_OT_select_more";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Select keyframes beside already selected ones";
|
2010-02-07 11:50:03 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= graphkeys_select_more_exec;
|
|
|
|
ot->poll= graphop_visible_keyframes_poll;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------- */
|
|
|
|
|
2010-10-15 01:36:14 +00:00
|
|
|
static int graphkeys_select_less_exec (bContext *C, wmOperator *UNUSED(op))
|
2010-02-07 11:50:03 +00:00
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* perform select changes */
|
|
|
|
select_moreless_graph_keys(&ac, SELMAP_LESS);
|
|
|
|
|
|
|
|
/* set notifier that keyframe selection has changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|NA_SELECTED, NULL);
|
2010-02-07 11:50:03 +00:00
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
void GRAPH_OT_select_less (wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name = "Select Less";
|
|
|
|
ot->idname= "GRAPH_OT_select_less";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description = "Deselect keyframes on ends of selection islands";
|
2010-02-07 11:50:03 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->exec= graphkeys_select_less_exec;
|
|
|
|
ot->poll= graphop_visible_keyframes_poll;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER/*|OPTYPE_UNDO*/;
|
|
|
|
}
|
|
|
|
|
2011-02-14 02:50:52 +00:00
|
|
|
/* ******************** Select Left/Right Operator ************************* */
|
|
|
|
/* Select keyframes left/right of the current frame indicator */
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* defines for left-right select tool */
|
2009-04-12 08:17:46 +00:00
|
|
|
static EnumPropertyItem prop_graphkeys_leftright_select_types[] = {
|
2009-06-16 00:52:21 +00:00
|
|
|
{GRAPHKEYS_LRSEL_TEST, "CHECK", 0, "Check if Select Left or Right", ""},
|
|
|
|
{GRAPHKEYS_LRSEL_LEFT, "LEFT", 0, "Before current frame", ""},
|
|
|
|
{GRAPHKEYS_LRSEL_RIGHT, "RIGHT", 0, "After current frame", ""},
|
|
|
|
{0, NULL, 0, NULL, NULL}
|
2009-01-26 23:18:27 +00:00
|
|
|
};
|
|
|
|
|
2011-02-14 02:50:52 +00:00
|
|
|
/* --------------------------------- */
|
|
|
|
|
|
|
|
static void graphkeys_select_leftright (bAnimContext *ac, short leftright, short select_mode)
|
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
|
|
|
KeyframeEditFunc ok_cb, select_cb;
|
2011-03-05 10:29:10 +00:00
|
|
|
KeyframeEditData ked= {{NULL}};
|
2011-02-14 02:50:52 +00:00
|
|
|
Scene *scene= ac->scene;
|
|
|
|
|
|
|
|
/* if select mode is replace, deselect all keyframes (and channels) first */
|
|
|
|
if (select_mode==SELECT_REPLACE) {
|
|
|
|
select_mode= SELECT_ADD;
|
|
|
|
|
2011-11-12 05:00:24 +00:00
|
|
|
/* - deselect all other keyframes, so that just the newly selected remain
|
|
|
|
* - channels aren't deselected, since we don't re-select any as a consequence
|
|
|
|
*/
|
2011-11-15 12:02:44 +00:00
|
|
|
deselect_graph_keys(ac, 0, SELECT_SUBTRACT, FALSE);
|
2011-02-14 02:50:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* set callbacks and editing data */
|
|
|
|
ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
|
|
|
|
select_cb= ANIM_editkeyframes_select(select_mode);
|
|
|
|
|
|
|
|
if (leftright == GRAPHKEYS_LRSEL_LEFT) {
|
|
|
|
ked.f1 = MINAFRAMEF;
|
|
|
|
ked.f2 = (float)(CFRA + 0.1f);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
ked.f1 = (float)(CFRA - 0.1f);
|
|
|
|
ked.f2 = MAXFRAMEF;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* filter data */
|
Animation Channel Filtering Refactor - Part 3 (Visibility Flag Split)
* This (big) commit is aimed at cleaning up the filtering flags used
by the animation channel filtering code. The list of filtering flags
has been growing a bit "organically" since it's humble origins for use
in the Action Editor some 3 years (IIRC) ago now during a weekend
hackathon. Obviously, some things have ended up tacked on, while
others have been the product of other flag options. Nevertheless, it
was time for a bit of a spring clean!
* Most notably, one area where the system outgrown its original design
for the Action Editor was in terms of the "visibility" filtering flag
it was using. While in the Action Editor the concept of what channels
to include was strictly dictated by whether the channel hierarchy
showed it, in the Graph Editor this is not always the case. In other
words, there was a difference between the data the channels
represented being visible and the channels for that data being visible
in the hierarchy.
Long story short: this lead to bug report [#27076] (and many like it),
where if you selected an F-Curve, then collapsed the Group it was in,
then even after selecting another F-Curve in another Group, the
original F-Curve's properties would still be shown in the Properties
Region. The good news is that this commit fixes this issue right away!
* More good news will follow, as I start checking on the flag usage of
other tools, but I'm committing this first so that we have a stable
reference (of code similar to the old buggy stuff) on which we can
fall back to later to find bugs (should they pop up).
Anyways, back to the trenches!
2011-06-22 11:41:26 +00:00
|
|
|
filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_NODUPLIS);
|
2011-02-14 02:50:52 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
/* select keys */
|
|
|
|
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_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
|
|
|
|
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 1);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Cleanup */
|
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ----------------- */
|
|
|
|
|
|
|
|
static int graphkeys_select_leftright_exec (bContext *C, wmOperator *op)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short leftright = RNA_enum_get(op->ptr, "mode");
|
|
|
|
short selectmode;
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* select mode is either replace (deselect all, then add) or add/extend */
|
|
|
|
if (RNA_boolean_get(op->ptr, "extend"))
|
|
|
|
selectmode= SELECT_INVERT;
|
|
|
|
else
|
|
|
|
selectmode= SELECT_REPLACE;
|
|
|
|
|
|
|
|
/* if "test" mode is set, we don't have any info to set this with */
|
|
|
|
if (leftright == GRAPHKEYS_LRSEL_TEST)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* do the selecting now */
|
|
|
|
graphkeys_select_leftright(&ac, leftright, selectmode);
|
|
|
|
|
|
|
|
/* set notifier that keyframe selection (and channels too) have changed */
|
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|ND_ANIMCHAN|NA_SELECTED, NULL);
|
|
|
|
|
|
|
|
return OPERATOR_FINISHED;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int graphkeys_select_leftright_invoke (bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short leftright = RNA_enum_get(op->ptr, "mode");
|
|
|
|
|
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
|
|
|
|
|
|
|
/* handle mode-based testing */
|
|
|
|
if (leftright == GRAPHKEYS_LRSEL_TEST) {
|
|
|
|
Scene *scene= ac.scene;
|
|
|
|
ARegion *ar= ac.ar;
|
|
|
|
View2D *v2d= &ar->v2d;
|
|
|
|
float x;
|
2011-05-20 07:40:05 +00:00
|
|
|
|
2011-02-14 02:50:52 +00:00
|
|
|
/* determine which side of the current frame mouse is on */
|
2011-05-20 07:40:05 +00:00
|
|
|
UI_view2d_region_to_view(v2d, event->mval[0], event->mval[1], &x, NULL);
|
2011-02-14 02:50:52 +00:00
|
|
|
if (x < CFRA)
|
2011-05-20 18:00:19 +00:00
|
|
|
RNA_enum_set(op->ptr, "mode", GRAPHKEYS_LRSEL_LEFT);
|
2011-02-14 02:50:52 +00:00
|
|
|
else
|
2011-05-20 18:00:19 +00:00
|
|
|
RNA_enum_set(op->ptr, "mode", GRAPHKEYS_LRSEL_RIGHT);
|
2011-02-14 02:50:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* perform selection */
|
|
|
|
return graphkeys_select_leftright_exec(C, op);
|
|
|
|
}
|
|
|
|
|
|
|
|
void GRAPH_OT_select_leftright (wmOperatorType *ot)
|
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Select Left/Right";
|
|
|
|
ot->idname= "GRAPH_OT_select_leftright";
|
2011-02-14 03:04:59 +00:00
|
|
|
ot->description= "Select keyframes to the left or the right of the current frame";
|
2011-02-14 02:50:52 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= graphkeys_select_leftright_invoke;
|
|
|
|
ot->exec= graphkeys_select_leftright_exec;
|
|
|
|
ot->poll= graphop_visible_keyframes_poll;
|
|
|
|
|
|
|
|
/* flags */
|
|
|
|
ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
|
|
|
|
|
|
|
|
/* id-props */
|
|
|
|
ot->prop= RNA_def_enum(ot->srna, "mode", prop_graphkeys_leftright_select_types, GRAPHKEYS_LRSEL_TEST, "Mode", "");
|
|
|
|
RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", "");
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ******************** Mouse-Click Select Operator *********************** */
|
|
|
|
/* This operator works in one of three ways:
|
|
|
|
* - 1) keyframe under mouse - no special modifiers
|
|
|
|
* - 2) all keyframes on the same side of current frame indicator as mouse - ALT modifier
|
|
|
|
* - 3) column select all keyframes in frame under mouse - CTRL modifier
|
|
|
|
*
|
|
|
|
* In addition to these basic options, the SHIFT modifier can be used to toggle the
|
|
|
|
* selection mode between replacing the selection (without) and inverting the selection (with).
|
|
|
|
*/
|
2009-01-27 05:04:23 +00:00
|
|
|
|
2010-03-09 07:09:38 +00:00
|
|
|
/* temp info for caching handle vertices close */
|
|
|
|
typedef struct tNearestVertInfo {
|
|
|
|
struct tNearestVertInfo *next, *prev;
|
|
|
|
|
|
|
|
FCurve *fcu; /* F-Curve that keyframe comes from */
|
|
|
|
|
|
|
|
BezTriple *bezt; /* keyframe to consider */
|
|
|
|
FPoint *fpt; /* sample point to consider */
|
|
|
|
|
|
|
|
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 */
|
|
|
|
} tNearestVertInfo;
|
|
|
|
|
|
|
|
/* Tags for the type of graph vert that we have */
|
|
|
|
typedef enum eGraphVertIndex {
|
|
|
|
NEAREST_HANDLE_LEFT = -1,
|
2009-01-27 05:04:23 +00:00
|
|
|
NEAREST_HANDLE_KEY,
|
|
|
|
NEAREST_HANDLE_RIGHT
|
2010-03-09 07:09:38 +00:00
|
|
|
} eGraphVertIndex;
|
|
|
|
|
|
|
|
/* Tolerance for absolute radius (in pixels) of the vert from the cursor to use */
|
|
|
|
// TODO: perhaps this should depend a bit on the size that the user set the vertices to be?
|
|
|
|
#define GVERTSEL_TOL 10
|
|
|
|
|
|
|
|
/* ....... */
|
2010-02-08 18:00:27 +00:00
|
|
|
|
|
|
|
/* check if its ok to select a handle */
|
|
|
|
// XXX also need to check for int-values only?
|
|
|
|
static int 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;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2010-03-09 07:09:38 +00:00
|
|
|
/* check if the given vertex is within bounds or not */
|
|
|
|
// TODO: should we return if we hit something?
|
2011-05-20 07:40:05 +00:00
|
|
|
static void nearest_fcurve_vert_store (ListBase *matches, View2D *v2d, FCurve *fcu, BezTriple *bezt, FPoint *fpt, short hpoint, const int mval[2])
|
2010-03-09 07:09:38 +00:00
|
|
|
{
|
|
|
|
/* Keyframes or Samples? */
|
|
|
|
if (bezt) {
|
|
|
|
int screen_co[2], dist;
|
|
|
|
|
|
|
|
/* convert from data-space to screen coordinates
|
|
|
|
* NOTE: hpoint+1 gives us 0,1,2 respectively for each handle,
|
|
|
|
* needed to access the relevant vertex coordinates in the 3x3
|
|
|
|
* 'vec' matrix
|
|
|
|
*/
|
2010-05-22 04:54:34 +00:00
|
|
|
UI_view2d_view_to_region(v2d, bezt->vec[hpoint+1][0], bezt->vec[hpoint+1][1], &screen_co[0], &screen_co[1]);
|
2010-03-09 07:09:38 +00:00
|
|
|
|
|
|
|
/* check if distance from mouse cursor to vert in screen space is within tolerance */
|
|
|
|
// XXX: inlined distance calculation, since we cannot do this on ints using the math lib...
|
|
|
|
//dist = len_v2v2(mval, screen_co);
|
|
|
|
dist = sqrt((mval[0] - screen_co[0])*(mval[0] - screen_co[0]) +
|
|
|
|
(mval[1] - screen_co[1])*(mval[1] - screen_co[1]));
|
|
|
|
|
|
|
|
if (dist <= GVERTSEL_TOL) {
|
|
|
|
tNearestVertInfo *nvi = (tNearestVertInfo *)matches->last;
|
|
|
|
short replace = 0;
|
|
|
|
|
|
|
|
/* 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)) )
|
|
|
|
replace= 1;
|
|
|
|
}
|
|
|
|
/* add new if not replacing... */
|
|
|
|
if (replace == 0)
|
|
|
|
nvi = MEM_callocN(sizeof(tNearestVertInfo), "Nearest Graph Vert Info - Bezt");
|
|
|
|
|
|
|
|
/* store values */
|
|
|
|
nvi->fcu = fcu;
|
|
|
|
nvi->bezt = bezt;
|
|
|
|
nvi->hpoint = hpoint;
|
|
|
|
nvi->dist = dist;
|
|
|
|
|
|
|
|
nvi->sel= BEZSELECTED(bezt); // XXX... should this use the individual verts instead?
|
|
|
|
|
|
|
|
/* add to list of matches if appropriate... */
|
|
|
|
if (replace == 0)
|
|
|
|
BLI_addtail(matches, nvi);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (fpt) {
|
|
|
|
// TODO...
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* helper for find_nearest_fcurve_vert() - build the list of nearest matches */
|
2011-05-20 07:40:05 +00:00
|
|
|
static void get_nearest_fcurve_verts_list (bAnimContext *ac, const int mval[2], ListBase *matches)
|
2009-01-27 05:04:23 +00:00
|
|
|
{
|
|
|
|
ListBase anim_data = {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
2011-06-21 01:41:39 +00:00
|
|
|
SpaceIpo *sipo= (SpaceIpo *)ac->sl;
|
2009-01-27 05:04:23 +00:00
|
|
|
View2D *v2d= &ac->ar->v2d;
|
|
|
|
|
2009-07-28 06:50:30 +00:00
|
|
|
/* get curves to search through
|
|
|
|
* - if the option to only show keyframes that belong to selected F-Curves is enabled,
|
|
|
|
* include the 'only selected' flag...
|
|
|
|
*/
|
Animation Channel Filtering Refactor - Part 3 (Visibility Flag Split)
* This (big) commit is aimed at cleaning up the filtering flags used
by the animation channel filtering code. The list of filtering flags
has been growing a bit "organically" since it's humble origins for use
in the Action Editor some 3 years (IIRC) ago now during a weekend
hackathon. Obviously, some things have ended up tacked on, while
others have been the product of other flag options. Nevertheless, it
was time for a bit of a spring clean!
* Most notably, one area where the system outgrown its original design
for the Action Editor was in terms of the "visibility" filtering flag
it was using. While in the Action Editor the concept of what channels
to include was strictly dictated by whether the channel hierarchy
showed it, in the Graph Editor this is not always the case. In other
words, there was a difference between the data the channels
represented being visible and the channels for that data being visible
in the hierarchy.
Long story short: this lead to bug report [#27076] (and many like it),
where if you selected an F-Curve, then collapsed the Group it was in,
then even after selecting another F-Curve in another Group, the
original F-Curve's properties would still be shown in the Properties
Region. The good news is that this commit fixes this issue right away!
* More good news will follow, as I start checking on the flag usage of
other tools, but I'm committing this first so that we have a stable
reference (of code similar to the old buggy stuff) on which we can
fall back to later to find bugs (should they pop up).
Anyways, back to the trenches!
2011-06-22 11:41:26 +00:00
|
|
|
filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
|
2010-01-22 23:51:31 +00:00
|
|
|
if (sipo->flag & SIPO_SELCUVERTSONLY) // FIXME: this should really be check for by the filtering code...
|
2009-07-28 06:50:30 +00:00
|
|
|
filter |= ANIMFILTER_SEL;
|
2009-01-27 05:04:23 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
|
|
|
FCurve *fcu= (FCurve *)ale->key_data;
|
2009-06-23 13:25:31 +00:00
|
|
|
AnimData *adt= ANIM_nla_mapping_get(ac, ale);
|
2009-01-27 05:04:23 +00:00
|
|
|
|
2010-01-26 03:16:14 +00:00
|
|
|
/* apply unit corrections */
|
2010-01-26 09:25:32 +00:00
|
|
|
ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, 0);
|
2010-01-26 03:16:14 +00:00
|
|
|
|
2010-03-09 07:09:38 +00:00
|
|
|
/* apply NLA mapping to all the keyframes */
|
|
|
|
if (adt)
|
2011-03-09 15:04:09 +00:00
|
|
|
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 0, 0);
|
2010-03-09 07:09:38 +00:00
|
|
|
|
2009-01-27 05:04:23 +00:00
|
|
|
if (fcu->bezt) {
|
|
|
|
BezTriple *bezt1=fcu->bezt, *prevbezt=NULL;
|
2010-03-09 07:09:38 +00:00
|
|
|
int i;
|
2009-06-23 13:25:31 +00:00
|
|
|
|
2009-01-27 05:04:23 +00:00
|
|
|
for (i=0; i < fcu->totvert; i++, prevbezt=bezt1, bezt1++) {
|
2010-03-09 07:09:38 +00:00
|
|
|
/* keyframe */
|
|
|
|
nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_KEY, mval);
|
2009-01-27 05:04:23 +00:00
|
|
|
|
|
|
|
/* handles - only do them if they're visible */
|
2010-03-09 07:09:38 +00:00
|
|
|
if (fcurve_handle_sel_check(sipo, bezt1) && (fcu->totvert > 1)) {
|
2009-01-27 05:04:23 +00:00
|
|
|
/* first handle only visible if previous segment had handles */
|
|
|
|
if ( (!prevbezt && (bezt1->ipo==BEZT_IPO_BEZ)) || (prevbezt && (prevbezt->ipo==BEZT_IPO_BEZ)) )
|
|
|
|
{
|
2010-03-09 07:09:38 +00:00
|
|
|
nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_LEFT, mval);
|
2009-01-27 05:04:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* second handle only visible if this segment is bezier */
|
|
|
|
if (bezt1->ipo == BEZT_IPO_BEZ)
|
|
|
|
{
|
2010-03-09 07:09:38 +00:00
|
|
|
nearest_fcurve_vert_store(matches, v2d, fcu, bezt1, NULL, NEAREST_HANDLE_RIGHT, mval);
|
2009-01-27 05:04:23 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-03-09 07:09:38 +00:00
|
|
|
}
|
|
|
|
else if (fcu->fpt) {
|
|
|
|
// TODO; do this for samples too
|
2009-06-23 13:25:31 +00:00
|
|
|
|
2009-01-27 05:04:23 +00:00
|
|
|
}
|
2010-01-26 03:16:14 +00:00
|
|
|
|
2010-03-09 07:09:38 +00:00
|
|
|
/* un-apply NLA mapping from all the keyframes */
|
|
|
|
if (adt)
|
2011-03-09 15:04:09 +00:00
|
|
|
ANIM_nla_mapping_apply_fcurve(adt, ale->key_data, 1, 0);
|
2010-03-09 07:09:38 +00:00
|
|
|
|
2010-01-26 03:16:14 +00:00
|
|
|
/* unapply unit corrections */
|
2010-01-26 09:25:32 +00:00
|
|
|
ANIM_unit_mapping_apply_fcurve(ac->scene, ale->id, ale->key_data, ANIM_UNITCONV_RESTORE);
|
2009-01-27 05:04:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* free channels */
|
|
|
|
BLI_freelistN(&anim_data);
|
2010-03-09 07:09:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* helper for find_nearest_fcurve_vert() - get the best match to use */
|
2010-10-16 08:03:28 +00:00
|
|
|
static tNearestVertInfo *get_best_nearest_fcurve_vert (ListBase *matches)
|
2010-03-09 07:09:38 +00:00
|
|
|
{
|
|
|
|
tNearestVertInfo *nvi = NULL;
|
|
|
|
short found = 0;
|
2009-01-27 05:04:23 +00:00
|
|
|
|
2010-03-09 07:09:38 +00:00
|
|
|
/* abort if list is empty */
|
|
|
|
if (matches->first == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
/* if list only has 1 item, remove it from the list and return */
|
|
|
|
if (matches->first == matches->last) {
|
|
|
|
/* need to remove from the list, otherwise it gets freed and then we can't return it */
|
|
|
|
nvi= matches->first;
|
|
|
|
BLI_remlink(matches, nvi);
|
|
|
|
|
|
|
|
return nvi;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* try to find the first selected F-Curve vert, then take the one after it */
|
|
|
|
for (nvi = matches->first; nvi; nvi = nvi->next) {
|
|
|
|
/* which mode of search are we in: find first selected, or find vert? */
|
|
|
|
if (found) {
|
|
|
|
/* just take this vert now that we've found the selected one
|
|
|
|
* - we'll need to remove this from the list so that it can be returned to the original caller
|
|
|
|
*/
|
|
|
|
BLI_remlink(matches, nvi);
|
|
|
|
return nvi;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* if vert is selected, we've got what we want... */
|
|
|
|
if (nvi->sel)
|
|
|
|
found= 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* if we're still here, this means that we failed to find anything appropriate in the first pass,
|
|
|
|
* so just take the first item now...
|
|
|
|
*/
|
|
|
|
nvi = matches->first;
|
|
|
|
BLI_remlink(matches, nvi);
|
|
|
|
return nvi;
|
2009-01-27 05:04:23 +00:00
|
|
|
}
|
2010-03-09 07:09:38 +00:00
|
|
|
|
|
|
|
/* Find the nearest vertices (either a handle or the keyframe) that are nearest to the mouse cursor (in area coordinates)
|
|
|
|
* NOTE: the match info found must still be freed
|
|
|
|
*/
|
2011-05-20 07:40:05 +00:00
|
|
|
static tNearestVertInfo *find_nearest_fcurve_vert (bAnimContext *ac, const int mval[2])
|
2010-03-09 07:09:38 +00:00
|
|
|
{
|
|
|
|
ListBase matches = {NULL, NULL};
|
|
|
|
tNearestVertInfo *nvi;
|
|
|
|
|
|
|
|
/* step 1: get the nearest verts */
|
|
|
|
get_nearest_fcurve_verts_list(ac, mval, &matches);
|
|
|
|
|
|
|
|
/* step 2: find the best vert */
|
2010-10-16 08:03:28 +00:00
|
|
|
nvi= get_best_nearest_fcurve_vert(&matches);
|
2010-03-09 07:09:38 +00:00
|
|
|
|
|
|
|
BLI_freelistN(&matches);
|
|
|
|
|
|
|
|
/* return the best vert found */
|
|
|
|
return nvi;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
2009-01-26 23:18:27 +00:00
|
|
|
/* option 1) select keyframe directly under mouse */
|
2011-05-20 07:40:05 +00:00
|
|
|
static void mouse_graph_keys (bAnimContext *ac, const int mval[2], short select_mode, short curves_only)
|
2009-01-26 23:18:27 +00:00
|
|
|
{
|
2011-06-21 01:41:39 +00:00
|
|
|
SpaceIpo *sipo= (SpaceIpo *)ac->sl;
|
2010-03-09 07:09:38 +00:00
|
|
|
tNearestVertInfo *nvi;
|
2010-12-15 15:59:10 +00:00
|
|
|
BezTriple *bezt= NULL;
|
2009-01-27 05:04:23 +00:00
|
|
|
|
|
|
|
/* find the beztriple that we're selecting, and the handle that was clicked on */
|
2010-03-09 07:09:38 +00:00
|
|
|
nvi = find_nearest_fcurve_vert(ac, mval);
|
2009-01-27 05:04:23 +00:00
|
|
|
|
|
|
|
/* check if anything to select */
|
2010-03-09 07:09:38 +00:00
|
|
|
if (nvi == NULL)
|
2009-01-27 05:04:23 +00:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* deselect all other curves? */
|
2009-04-12 08:17:46 +00:00
|
|
|
if (select_mode == SELECT_REPLACE) {
|
|
|
|
/* reset selection mode */
|
|
|
|
select_mode= SELECT_ADD;
|
|
|
|
|
2011-11-15 12:02:44 +00:00
|
|
|
/* deselect all other keyframes (+ F-Curves too) */
|
|
|
|
deselect_graph_keys(ac, 0, SELECT_SUBTRACT, TRUE);
|
2010-01-22 23:51:31 +00:00
|
|
|
|
|
|
|
/* deselect other channels too, but only only do this if
|
|
|
|
* selection of channel when the visibility of keyframes
|
|
|
|
* doesn't depend on this
|
|
|
|
*/
|
|
|
|
if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0)
|
2010-01-23 03:04:37 +00:00
|
|
|
ANIM_deselect_anim_channels(ac, ac->data, ac->datatype, 0, ACHANNEL_SETFLAG_CLEAR);
|
2009-01-27 05:04:23 +00:00
|
|
|
}
|
|
|
|
|
2009-04-12 08:17:46 +00:00
|
|
|
/* if points can be selected on this F-Curve */
|
|
|
|
// TODO: what about those with no keyframes?
|
2010-03-09 07:09:38 +00:00
|
|
|
if ((curves_only == 0) && ((nvi->fcu->flag & FCURVE_PROTECTED)==0)) {
|
2009-01-27 05:04:23 +00:00
|
|
|
/* only if there's keyframe */
|
2010-03-09 07:09:38 +00:00
|
|
|
if (nvi->bezt) {
|
2010-12-15 15:59:10 +00:00
|
|
|
bezt= nvi->bezt; /* used to check bezt seletion is set */
|
2009-01-27 05:04:23 +00:00
|
|
|
/* depends on selection mode */
|
2009-04-12 08:17:46 +00:00
|
|
|
if (select_mode == SELECT_INVERT) {
|
2009-01-27 05:04:23 +00:00
|
|
|
/* keyframe - invert select of all */
|
2010-03-09 07:09:38 +00:00
|
|
|
if (nvi->hpoint == NEAREST_HANDLE_KEY) {
|
2009-01-27 05:04:23 +00:00
|
|
|
if (BEZSELECTED(bezt)) {
|
|
|
|
BEZ_DESEL(bezt);
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
BEZ_SEL(bezt);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/* handles - toggle selection of relevant handle */
|
2010-03-09 07:09:38 +00:00
|
|
|
else if (nvi->hpoint == NEAREST_HANDLE_LEFT) {
|
2009-01-27 05:04:23 +00:00
|
|
|
/* toggle selection */
|
|
|
|
bezt->f1 ^= SELECT;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* toggle selection */
|
|
|
|
bezt->f3 ^= SELECT;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* if the keyframe was clicked on, select all verts of given beztriple */
|
2010-03-09 07:09:38 +00:00
|
|
|
if (nvi->hpoint == NEAREST_HANDLE_KEY) {
|
2009-01-27 05:04:23 +00:00
|
|
|
BEZ_SEL(bezt);
|
|
|
|
}
|
|
|
|
/* otherwise, select the handle that applied */
|
2010-03-09 07:09:38 +00:00
|
|
|
else if (nvi->hpoint == NEAREST_HANDLE_LEFT)
|
2009-01-27 05:04:23 +00:00
|
|
|
bezt->f1 |= SELECT;
|
|
|
|
else
|
|
|
|
bezt->f3 |= SELECT;
|
|
|
|
}
|
|
|
|
}
|
2010-03-09 07:09:38 +00:00
|
|
|
else if (nvi->fpt) {
|
|
|
|
// TODO: need to handle sample points
|
|
|
|
}
|
2009-01-27 05:04:23 +00:00
|
|
|
}
|
2009-04-12 08:17:46 +00:00
|
|
|
else {
|
2010-04-02 12:02:39 +00:00
|
|
|
KeyframeEditFunc select_cb;
|
|
|
|
KeyframeEditData ked;
|
2009-07-28 06:50:30 +00:00
|
|
|
|
2009-04-12 08:17:46 +00:00
|
|
|
/* initialise keyframe editing data */
|
2010-04-02 12:02:39 +00:00
|
|
|
memset(&ked, 0, sizeof(KeyframeEditData));
|
2009-04-12 08:17:46 +00:00
|
|
|
|
|
|
|
/* set up BezTriple edit callbacks */
|
|
|
|
select_cb= ANIM_editkeyframes_select(select_mode);
|
|
|
|
|
|
|
|
/* select all keyframes */
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, nvi->fcu, NULL, select_cb, NULL);
|
2009-04-12 08:17:46 +00:00
|
|
|
}
|
2009-02-09 10:33:05 +00:00
|
|
|
|
2010-01-22 23:51:31 +00:00
|
|
|
/* only change selection of channel when the visibility of keyframes doesn't depend on this */
|
|
|
|
if ((sipo->flag & SIPO_SELCUVERTSONLY) == 0) {
|
|
|
|
/* select or deselect curve? */
|
2011-02-14 02:50:52 +00:00
|
|
|
if (bezt) {
|
|
|
|
/* 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))
|
2010-12-15 15:59:10 +00:00
|
|
|
nvi->fcu->flag |= FCURVE_SELECTED;
|
2011-02-14 02:50:52 +00:00
|
|
|
else
|
2010-12-15 15:59:10 +00:00
|
|
|
nvi->fcu->flag &= ~FCURVE_SELECTED;
|
|
|
|
}
|
|
|
|
else {
|
2011-02-14 02:50:52 +00:00
|
|
|
/* didn't hit any channel, so just apply that selection mode to the curve's selection status */
|
2010-12-15 15:59:10 +00:00
|
|
|
if (select_mode == SELECT_INVERT)
|
|
|
|
nvi->fcu->flag ^= FCURVE_SELECTED;
|
|
|
|
else if (select_mode == SELECT_ADD)
|
|
|
|
nvi->fcu->flag |= FCURVE_SELECTED;
|
|
|
|
}
|
2009-02-09 10:33:05 +00:00
|
|
|
}
|
2011-03-10 23:55:22 +00:00
|
|
|
|
|
|
|
/* set active F-Curve (NOTE: sync the filter flags with findnearest_fcurve_vert) */
|
|
|
|
/* needs to be called with (sipo->flag & SIPO_SELCUVERTSONLY) otherwise the active flag won't be set [#26452] */
|
|
|
|
if (nvi->fcu->flag & FCURVE_SELECTED) {
|
Animation Channel Filtering Refactor - Part 3 (Visibility Flag Split)
* This (big) commit is aimed at cleaning up the filtering flags used
by the animation channel filtering code. The list of filtering flags
has been growing a bit "organically" since it's humble origins for use
in the Action Editor some 3 years (IIRC) ago now during a weekend
hackathon. Obviously, some things have ended up tacked on, while
others have been the product of other flag options. Nevertheless, it
was time for a bit of a spring clean!
* Most notably, one area where the system outgrown its original design
for the Action Editor was in terms of the "visibility" filtering flag
it was using. While in the Action Editor the concept of what channels
to include was strictly dictated by whether the channel hierarchy
showed it, in the Graph Editor this is not always the case. In other
words, there was a difference between the data the channels
represented being visible and the channels for that data being visible
in the hierarchy.
Long story short: this lead to bug report [#27076] (and many like it),
where if you selected an F-Curve, then collapsed the Group it was in,
then even after selecting another F-Curve in another Group, the
original F-Curve's properties would still be shown in the Properties
Region. The good news is that this commit fixes this issue right away!
* More good news will follow, as I start checking on the flag usage of
other tools, but I'm committing this first so that we have a stable
reference (of code similar to the old buggy stuff) on which we can
fall back to later to find bugs (should they pop up).
Anyways, back to the trenches!
2011-06-22 11:41:26 +00:00
|
|
|
int filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
|
2011-03-10 23:55:22 +00:00
|
|
|
ANIM_set_active_channel(ac, ac->data, ac->datatype, filter, nvi->fcu, ANIMTYPE_FCURVE);
|
|
|
|
}
|
|
|
|
|
2010-03-09 07:09:38 +00:00
|
|
|
/* free temp sample data for filtering */
|
|
|
|
MEM_freeN(nvi);
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* Option 2) Selects all the keyframes on either side of the current frame (depends on which side the mouse is on) */
|
2011-02-14 02:50:52 +00:00
|
|
|
/* (see graphkeys_select_leftright) */
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* Option 3) Selects all visible keyframes in the same frame as the mouse click */
|
2011-05-20 07:40:05 +00:00
|
|
|
static void graphkeys_mselect_column (bAnimContext *ac, const int mval[2], short select_mode)
|
2009-01-26 23:18:27 +00:00
|
|
|
{
|
|
|
|
ListBase anim_data= {NULL, NULL};
|
|
|
|
bAnimListElem *ale;
|
|
|
|
int filter;
|
|
|
|
|
2010-04-02 12:02:39 +00:00
|
|
|
KeyframeEditFunc select_cb, ok_cb;
|
|
|
|
KeyframeEditData ked;
|
2010-03-09 07:09:38 +00:00
|
|
|
tNearestVertInfo *nvi;
|
2009-04-12 08:17:46 +00:00
|
|
|
float selx = (float)ac->scene->r.cfra;
|
|
|
|
|
2010-03-09 07:09:38 +00:00
|
|
|
/* find the beztriple that we're selecting, and the handle that was clicked on */
|
|
|
|
nvi = find_nearest_fcurve_vert(ac, mval);
|
2009-04-12 08:17:46 +00:00
|
|
|
|
|
|
|
/* check if anything to select */
|
2010-03-09 07:09:38 +00:00
|
|
|
if (nvi == NULL)
|
2009-04-12 08:17:46 +00:00
|
|
|
return;
|
2010-03-09 07:09:38 +00:00
|
|
|
|
|
|
|
/* get frame number on which elements should be selected */
|
|
|
|
// TODO: should we restrict to integer frames only?
|
|
|
|
if (nvi->bezt)
|
|
|
|
selx= nvi->bezt->vec[1][0];
|
|
|
|
else if (nvi->fpt)
|
|
|
|
selx= nvi->fpt->vec[0];
|
2009-04-12 08:17:46 +00:00
|
|
|
|
2011-11-15 12:02:44 +00:00
|
|
|
/* if select mode is replace, deselect all keyframes first */
|
2009-04-12 08:17:46 +00:00
|
|
|
if (select_mode==SELECT_REPLACE) {
|
|
|
|
/* reset selection mode to add to selection */
|
|
|
|
select_mode= SELECT_ADD;
|
|
|
|
|
2011-11-15 12:02:44 +00:00
|
|
|
/* - deselect all other keyframes, so that just the newly selected remain
|
|
|
|
* - channels aren't deselected, since we don't re-select any as a consequence
|
2010-01-22 23:51:31 +00:00
|
|
|
*/
|
2011-11-15 12:02:44 +00:00
|
|
|
deselect_graph_keys(ac, 0, SELECT_SUBTRACT, FALSE);
|
2009-04-12 08:17:46 +00:00
|
|
|
}
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* initialise keyframe editing data */
|
2010-04-02 12:02:39 +00:00
|
|
|
memset(&ked, 0, sizeof(KeyframeEditData));
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* set up BezTriple edit callbacks */
|
2009-04-12 08:17:46 +00:00
|
|
|
select_cb= ANIM_editkeyframes_select(select_mode);
|
2009-01-26 23:18:27 +00:00
|
|
|
ok_cb= ANIM_editkeyframes_ok(BEZT_OK_FRAME);
|
|
|
|
|
|
|
|
/* loop through all of the keys and select additional keyframes
|
|
|
|
* based on the keys found to be selected above
|
|
|
|
*/
|
Animation Channel Filtering Refactor - Part 3 (Visibility Flag Split)
* This (big) commit is aimed at cleaning up the filtering flags used
by the animation channel filtering code. The list of filtering flags
has been growing a bit "organically" since it's humble origins for use
in the Action Editor some 3 years (IIRC) ago now during a weekend
hackathon. Obviously, some things have ended up tacked on, while
others have been the product of other flag options. Nevertheless, it
was time for a bit of a spring clean!
* Most notably, one area where the system outgrown its original design
for the Action Editor was in terms of the "visibility" filtering flag
it was using. While in the Action Editor the concept of what channels
to include was strictly dictated by whether the channel hierarchy
showed it, in the Graph Editor this is not always the case. In other
words, there was a difference between the data the channels
represented being visible and the channels for that data being visible
in the hierarchy.
Long story short: this lead to bug report [#27076] (and many like it),
where if you selected an F-Curve, then collapsed the Group it was in,
then even after selecting another F-Curve in another Group, the
original F-Curve's properties would still be shown in the Properties
Region. The good news is that this commit fixes this issue right away!
* More good news will follow, as I start checking on the flag usage of
other tools, but I'm committing this first so that we have a stable
reference (of code similar to the old buggy stuff) on which we can
fall back to later to find bugs (should they pop up).
Anyways, back to the trenches!
2011-06-22 11:41:26 +00:00
|
|
|
filter= (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_CURVE_VISIBLE | ANIMFILTER_NODUPLIS);
|
2009-01-26 23:18:27 +00:00
|
|
|
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
|
|
|
|
|
|
|
for (ale= anim_data.first; ale; ale= ale->next) {
|
2009-06-23 13:25:31 +00:00
|
|
|
AnimData *adt= ANIM_nla_mapping_get(ac, ale);
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* set frame for validation callback to refer to */
|
2009-06-23 13:25:31 +00:00
|
|
|
if (adt)
|
2010-04-02 12:02:39 +00:00
|
|
|
ked.f1= BKE_nla_tweakedit_remap(adt, selx, NLATIME_CONVERT_UNMAP);
|
2009-01-26 23:18:27 +00:00
|
|
|
else
|
2010-04-02 12:02:39 +00:00
|
|
|
ked.f1= selx;
|
2009-01-26 23:18:27 +00:00
|
|
|
|
2009-01-27 05:04:23 +00:00
|
|
|
/* select elements with frame number matching cfra */
|
2010-04-02 12:02:39 +00:00
|
|
|
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, ok_cb, select_cb, NULL);
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* free elements */
|
2010-03-09 07:09:38 +00:00
|
|
|
MEM_freeN(nvi);
|
2010-04-02 12:02:39 +00:00
|
|
|
BLI_freelistN(&ked.list);
|
2009-01-26 23:18:27 +00:00
|
|
|
BLI_freelistN(&anim_data);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* ------------------- */
|
|
|
|
|
|
|
|
/* handle clicking */
|
|
|
|
static int graphkeys_clickselect_invoke(bContext *C, wmOperator *op, wmEvent *event)
|
|
|
|
{
|
|
|
|
bAnimContext ac;
|
|
|
|
short selectmode;
|
2011-05-20 07:40:05 +00:00
|
|
|
|
2009-01-26 23:18:27 +00:00
|
|
|
/* get editor data */
|
|
|
|
if (ANIM_animdata_get_context(C, &ac) == 0)
|
|
|
|
return OPERATOR_CANCELLED;
|
2011-05-20 07:40:05 +00:00
|
|
|
|
2009-01-26 23:18:27 +00:00
|
|
|
/* select mode is either replace (deselect all, then add) or add/extend */
|
2009-03-29 02:15:13 +00:00
|
|
|
if (RNA_boolean_get(op->ptr, "extend"))
|
2009-01-26 23:18:27 +00:00
|
|
|
selectmode= SELECT_INVERT;
|
|
|
|
else
|
|
|
|
selectmode= SELECT_REPLACE;
|
|
|
|
|
|
|
|
/* figure out action to take */
|
2011-02-14 02:50:52 +00:00
|
|
|
if (RNA_boolean_get(op->ptr, "column")) {
|
2009-04-12 08:17:46 +00:00
|
|
|
/* select all keyframes in the same frame as the one that was under the mouse */
|
2011-05-20 07:40:05 +00:00
|
|
|
graphkeys_mselect_column(&ac, event->mval, selectmode);
|
2009-04-12 08:17:46 +00:00
|
|
|
}
|
|
|
|
else if (RNA_boolean_get(op->ptr, "curves")) {
|
2011-02-14 02:50:52 +00:00
|
|
|
/* select all keyframes in the same F-Curve as the one under the mouse */
|
2011-05-20 07:40:05 +00:00
|
|
|
mouse_graph_keys(&ac, event->mval, selectmode, 1);
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
/* select keyframe under mouse */
|
2011-05-20 07:40:05 +00:00
|
|
|
mouse_graph_keys(&ac, event->mval, selectmode, 0);
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
|
2009-07-10 10:48:25 +00:00
|
|
|
/* set notifier that keyframe selection (and also channel selection in some cases) has changed */
|
2010-06-18 04:39:32 +00:00
|
|
|
WM_event_add_notifier(C, NC_ANIMATION|ND_KEYFRAME|ND_ANIMCHAN|NA_SELECTED, NULL);
|
2009-01-26 23:18:27 +00:00
|
|
|
|
2009-01-28 15:39:39 +00:00
|
|
|
/* for tweak grab to work */
|
2009-01-28 21:43:43 +00:00
|
|
|
return OPERATOR_FINISHED|OPERATOR_PASS_THROUGH;
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
|
2009-06-22 04:23:06 +00:00
|
|
|
void GRAPH_OT_clickselect (wmOperatorType *ot)
|
2009-01-26 23:18:27 +00:00
|
|
|
{
|
|
|
|
/* identifiers */
|
|
|
|
ot->name= "Mouse Select Keys";
|
2009-06-22 04:23:06 +00:00
|
|
|
ot->idname= "GRAPH_OT_clickselect";
|
2010-02-10 21:15:44 +00:00
|
|
|
ot->description= "Select keyframes by clicking on them";
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* api callbacks */
|
|
|
|
ot->invoke= graphkeys_clickselect_invoke;
|
2009-07-02 01:01:18 +00:00
|
|
|
ot->poll= graphop_visible_keyframes_poll;
|
2009-01-26 23:18:27 +00:00
|
|
|
|
|
|
|
/* id-props */
|
2009-03-29 02:15:13 +00:00
|
|
|
RNA_def_boolean(ot->srna, "extend", 0, "Extend Select", ""); // SHIFTKEY
|
2009-04-12 08:17:46 +00:00
|
|
|
RNA_def_boolean(ot->srna, "column", 0, "Column Select", "Select all keyframes that occur on the same frame as the one under the mouse"); // ALTKEY
|
|
|
|
RNA_def_boolean(ot->srna, "curves", 0, "Only Curves", "Select all the keyframes in the curve"); // CTRLKEY + ALTKEY
|
2009-01-26 23:18:27 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* ************************************************************************** */
|