Compare commits
2 Commits
tmp-eevee-
...
FixT87160_
Author | SHA1 | Date | |
---|---|---|---|
eb0a3c3b0c | |||
8694b428c7 |
@@ -745,6 +745,11 @@ static short ok_bezier_channel_circle(KeyframeEditData *ked, BezTriple *bezt)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static short ok_bezier_channel_all_are_valid(KeyframeEditData *ked, BezTriple *bezt)
|
||||
{
|
||||
return KEYFRAME_OK_KEY;
|
||||
}
|
||||
|
||||
KeyframeEditFunc ANIM_editkeyframes_ok(short mode)
|
||||
{
|
||||
/* eEditKeyframes_Validate */
|
||||
@@ -779,6 +784,8 @@ KeyframeEditFunc ANIM_editkeyframes_ok(short mode)
|
||||
case BEZT_OK_CHANNEL_CIRCLE:
|
||||
/* same as BEZT_OK_REGION_CIRCLE, but we're only using the x-value of the points */
|
||||
return ok_bezier_channel_circle;
|
||||
case BEZT_OK_ALL_ARE_VALID:
|
||||
return ok_bezier_channel_all_are_valid;
|
||||
default: /* nothing was ok */
|
||||
return NULL;
|
||||
}
|
||||
|
@@ -146,17 +146,19 @@ static void gpencil_frame_select(bGPDframe *gpf, short select_mode)
|
||||
}
|
||||
|
||||
/* set all/none/invert select (like above, but with SELECT_* modes) */
|
||||
void ED_gpencil_select_frames(bGPDlayer *gpl, short select_mode)
|
||||
bool ED_gpencil_select_frames(bGPDlayer *gpl, short select_mode)
|
||||
{
|
||||
/* error checking */
|
||||
if (gpl == NULL) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* handle according to mode */
|
||||
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
|
||||
gpencil_frame_select(gpf, select_mode);
|
||||
}
|
||||
|
||||
return !BLI_listbase_is_empty(&gpl->frames);
|
||||
}
|
||||
|
||||
/* set all/none/invert select */
|
||||
@@ -172,46 +174,56 @@ void ED_gpencil_layer_frame_select_set(bGPDlayer *gpl, short mode)
|
||||
}
|
||||
|
||||
/* select the frame in this layer that occurs on this frame (there should only be one at most) */
|
||||
void ED_gpencil_select_frame(bGPDlayer *gpl, int selx, short select_mode)
|
||||
bool ED_gpencil_select_frame(bGPDlayer *gpl, int selx, short select_mode)
|
||||
{
|
||||
bGPDframe *gpf;
|
||||
|
||||
if (gpl == NULL) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
gpf = BKE_gpencil_layer_frame_find(gpl, selx);
|
||||
|
||||
if (gpf) {
|
||||
gpencil_frame_select(gpf, select_mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* select the frames in this layer that occur within the bounds specified */
|
||||
void ED_gpencil_layer_frames_select_box(bGPDlayer *gpl, float min, float max, short select_mode)
|
||||
bool ED_gpencil_layer_frames_select_box(bGPDlayer *gpl, float min, float max, short select_mode)
|
||||
{
|
||||
if (gpl == NULL) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool any_in_region = false;
|
||||
|
||||
/* only select those frames which are in bounds */
|
||||
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
|
||||
if (IN_RANGE(gpf->framenum, min, max)) {
|
||||
any_in_region = true;
|
||||
gpencil_frame_select(gpf, select_mode);
|
||||
}
|
||||
}
|
||||
|
||||
return any_in_region;
|
||||
}
|
||||
|
||||
/* select the frames in this layer that occur within the lasso/circle region specified */
|
||||
void ED_gpencil_layer_frames_select_region(KeyframeEditData *ked,
|
||||
bool ED_gpencil_layer_frames_select_region(KeyframeEditData *ked,
|
||||
bGPDlayer *gpl,
|
||||
short tool,
|
||||
short select_mode)
|
||||
{
|
||||
if (gpl == NULL) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool any_in_region = false;
|
||||
|
||||
/* only select frames which are within the region */
|
||||
LISTBASE_FOREACH (bGPDframe *, gpf, &gpl->frames) {
|
||||
/* construct a dummy point coordinate to do this testing with */
|
||||
@@ -224,16 +236,36 @@ void ED_gpencil_layer_frames_select_region(KeyframeEditData *ked,
|
||||
if (tool == BEZT_OK_CHANNEL_LASSO) {
|
||||
/* Lasso */
|
||||
if (keyframe_region_lasso_test(ked->data, pt)) {
|
||||
any_in_region = true;
|
||||
gpencil_frame_select(gpf, select_mode);
|
||||
}
|
||||
}
|
||||
else if (tool == BEZT_OK_CHANNEL_CIRCLE) {
|
||||
/* Circle */
|
||||
if (keyframe_region_circle_test(ked->data, pt)) {
|
||||
any_in_region = true;
|
||||
gpencil_frame_select(gpf, select_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return any_in_region;
|
||||
}
|
||||
|
||||
bool ED_gpencil_select_layer_based_on_frames(bGPDlayer *layer)
|
||||
{
|
||||
if (layer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ED_gpencil_layer_frame_select_check(layer)) {
|
||||
layer->flag |= GP_LAYER_SELECT;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
layer->flag &= ~GP_LAYER_SELECT;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* ***************************************** */
|
||||
|
@@ -191,16 +191,17 @@ void ED_gpencil_layer_make_cfra_list(struct bGPDlayer *gpl, ListBase *elems, boo
|
||||
|
||||
bool ED_gpencil_layer_frame_select_check(struct bGPDlayer *gpl);
|
||||
void ED_gpencil_layer_frame_select_set(struct bGPDlayer *gpl, short mode);
|
||||
void ED_gpencil_layer_frames_select_box(struct bGPDlayer *gpl,
|
||||
bool ED_gpencil_layer_frames_select_box(struct bGPDlayer *gpl,
|
||||
float min,
|
||||
float max,
|
||||
short select_mode);
|
||||
void ED_gpencil_layer_frames_select_region(struct KeyframeEditData *ked,
|
||||
bool ED_gpencil_layer_frames_select_region(struct KeyframeEditData *ked,
|
||||
struct bGPDlayer *gpl,
|
||||
short tool,
|
||||
short select_mode);
|
||||
void ED_gpencil_select_frames(struct bGPDlayer *gpl, short select_mode);
|
||||
void ED_gpencil_select_frame(struct bGPDlayer *gpl, int selx, short select_mode);
|
||||
bool ED_gpencil_select_frames(struct bGPDlayer *gpl, short select_mode);
|
||||
bool ED_gpencil_select_frame(struct bGPDlayer *gpl, int selx, short select_mode);
|
||||
bool ED_gpencil_select_layer_based_on_frames(struct bGPDlayer *layer);
|
||||
|
||||
bool ED_gpencil_layer_frames_delete(struct bGPDlayer *gpl);
|
||||
void ED_gpencil_layer_frames_duplicate(struct bGPDlayer *gpl);
|
||||
|
@@ -58,6 +58,7 @@ typedef enum eEditKeyframes_Validate {
|
||||
/* Only for keyframes a certain Dopesheet channel */
|
||||
BEZT_OK_CHANNEL_LASSO,
|
||||
BEZT_OK_CHANNEL_CIRCLE,
|
||||
BEZT_OK_ALL_ARE_VALID,
|
||||
} eEditKeyframes_Validate;
|
||||
|
||||
/* ------------ */
|
||||
|
@@ -102,16 +102,17 @@ void ED_masklayer_make_cfra_list(struct MaskLayer *mask_layer, ListBase *elems,
|
||||
|
||||
bool ED_masklayer_frame_select_check(struct MaskLayer *mask_layer);
|
||||
void ED_masklayer_frame_select_set(struct MaskLayer *mask_layer, short mode);
|
||||
void ED_masklayer_frames_select_box(struct MaskLayer *mask_layer,
|
||||
bool ED_masklayer_frames_select_box(struct MaskLayer *mask_layer,
|
||||
float min,
|
||||
float max,
|
||||
short select_mode);
|
||||
void ED_masklayer_frames_select_region(struct KeyframeEditData *ked,
|
||||
bool ED_masklayer_frames_select_region(struct KeyframeEditData *ked,
|
||||
struct MaskLayer *mask_layer,
|
||||
short tool,
|
||||
short select_mode);
|
||||
void ED_mask_select_frames(struct MaskLayer *mask_layer, short select_mode);
|
||||
void ED_mask_select_frame(struct MaskLayer *mask_layer, int selx, short select_mode);
|
||||
bool ED_mask_select_frames(struct MaskLayer *mask_layer, short select_mode);
|
||||
bool ED_mask_select_frame(struct MaskLayer *mask_layer, int selx, short select_mode);
|
||||
bool ED_mask_select_layer_based_on_frames(struct MaskLayer *mask_layer);
|
||||
|
||||
bool ED_masklayer_frames_delete(struct MaskLayer *mask_layer);
|
||||
void ED_masklayer_frames_duplicate(struct MaskLayer *mask_layer);
|
||||
|
@@ -151,13 +151,13 @@ static void mask_layer_shape_select(MaskLayerShape *mask_layer_shape, short sele
|
||||
}
|
||||
|
||||
/* set all/none/invert select (like above, but with SELECT_* modes) */
|
||||
void ED_mask_select_frames(MaskLayer *mask_layer, short select_mode)
|
||||
bool ED_mask_select_frames(MaskLayer *mask_layer, short select_mode)
|
||||
{
|
||||
MaskLayerShape *mask_layer_shape;
|
||||
|
||||
/* error checking */
|
||||
if (mask_layer == NULL) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* handle according to mode */
|
||||
@@ -165,6 +165,7 @@ void ED_mask_select_frames(MaskLayer *mask_layer, short select_mode)
|
||||
mask_layer_shape = mask_layer_shape->next) {
|
||||
mask_layer_shape_select(mask_layer_shape, select_mode);
|
||||
}
|
||||
return !BLI_listbase_is_empty(&mask_layer->splines_shapes);
|
||||
}
|
||||
|
||||
/* set all/none/invert select */
|
||||
@@ -180,41 +181,65 @@ void ED_masklayer_frame_select_set(MaskLayer *mask_layer, short mode)
|
||||
}
|
||||
|
||||
/* select the frame in this layer that occurs on this frame (there should only be one at most) */
|
||||
void ED_mask_select_frame(MaskLayer *mask_layer, int selx, short select_mode)
|
||||
bool ED_mask_select_frame(MaskLayer *mask_layer, int selx, short select_mode)
|
||||
{
|
||||
MaskLayerShape *mask_layer_shape;
|
||||
|
||||
if (mask_layer == NULL) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
mask_layer_shape = BKE_mask_layer_shape_find_frame(mask_layer, selx);
|
||||
|
||||
if (mask_layer_shape) {
|
||||
mask_layer_shape_select(mask_layer_shape, select_mode);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ED_mask_select_layer_based_on_frames(struct MaskLayer *mask_layer)
|
||||
{
|
||||
if (mask_layer == NULL) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (ED_masklayer_frame_select_check(mask_layer)) {
|
||||
mask_layer->flag |= MASK_LAYERFLAG_SELECT;
|
||||
return true;
|
||||
}
|
||||
else {
|
||||
mask_layer->flag &= ~MASK_LAYERFLAG_SELECT;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/* select the frames in this layer that occur within the bounds specified */
|
||||
void ED_masklayer_frames_select_box(MaskLayer *mask_layer, float min, float max, short select_mode)
|
||||
bool ED_masklayer_frames_select_box(MaskLayer *mask_layer, float min, float max, short select_mode)
|
||||
{
|
||||
MaskLayerShape *mask_layer_shape;
|
||||
|
||||
if (mask_layer == NULL) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool any_in_region = false;
|
||||
|
||||
/* only select those frames which are in bounds */
|
||||
for (mask_layer_shape = mask_layer->splines_shapes.first; mask_layer_shape;
|
||||
mask_layer_shape = mask_layer_shape->next) {
|
||||
if (IN_RANGE(mask_layer_shape->frame, min, max)) {
|
||||
any_in_region = true;
|
||||
mask_layer_shape_select(mask_layer_shape, select_mode);
|
||||
}
|
||||
}
|
||||
|
||||
return any_in_region;
|
||||
}
|
||||
|
||||
/* select the frames in this layer that occur within the lasso/circle region specified */
|
||||
void ED_masklayer_frames_select_region(KeyframeEditData *ked,
|
||||
bool ED_masklayer_frames_select_region(KeyframeEditData *ked,
|
||||
MaskLayer *mask_layer,
|
||||
short tool,
|
||||
short select_mode)
|
||||
@@ -222,9 +247,11 @@ void ED_masklayer_frames_select_region(KeyframeEditData *ked,
|
||||
MaskLayerShape *mask_layer_shape;
|
||||
|
||||
if (mask_layer == NULL) {
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool any_in_region = false;
|
||||
|
||||
/* only select frames which are within the region */
|
||||
for (mask_layer_shape = mask_layer->splines_shapes.first; mask_layer_shape;
|
||||
mask_layer_shape = mask_layer_shape->next) {
|
||||
@@ -238,16 +265,20 @@ void ED_masklayer_frames_select_region(KeyframeEditData *ked,
|
||||
if (tool == BEZT_OK_CHANNEL_LASSO) {
|
||||
/* Lasso */
|
||||
if (keyframe_region_lasso_test(ked->data, pt)) {
|
||||
any_in_region = true;
|
||||
mask_layer_shape_select(mask_layer_shape, select_mode);
|
||||
}
|
||||
}
|
||||
else if (tool == BEZT_OK_CHANNEL_CIRCLE) {
|
||||
/* Circle */
|
||||
if (keyframe_region_circle_test(ked->data, pt)) {
|
||||
any_in_region = true;
|
||||
mask_layer_shape_select(mask_layer_shape, select_mode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return any_in_region;
|
||||
}
|
||||
|
||||
/* ***************************************** */
|
||||
|
@@ -66,6 +66,156 @@
|
||||
/* ************************************************************************** */
|
||||
/* KEYFRAMES STUFF */
|
||||
|
||||
static void actkeys_select_channel_based_on_keys(FCurve *fcu, short select_mode)
|
||||
{
|
||||
bool any_selected = false;
|
||||
BezTriple *cur_bezt = fcu->bezt;
|
||||
int i = 0;
|
||||
for (; i < fcu->totvert; cur_bezt++, i++) {
|
||||
if (BEZT_ISSEL_ANY(cur_bezt)) {
|
||||
any_selected = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (any_selected) {
|
||||
fcu->flag |= FCURVE_SELECTED;
|
||||
}
|
||||
else {
|
||||
fcu->flag &= ~FCURVE_SELECTED;
|
||||
}
|
||||
}
|
||||
|
||||
static void actkeys_channel_set_active(bAnimListElem *ale)
|
||||
{
|
||||
switch (ale->datatype) {
|
||||
case ALE_FCURVE:
|
||||
((FCurve *)ale->key_data)->flag |= FCURVE_ACTIVE;
|
||||
break;
|
||||
case ALE_GPFRAME:
|
||||
((bGPDlayer *)ale->data)->flag |= GP_LAYER_ACTIVE;
|
||||
break;
|
||||
case ALE_MASKLAY:
|
||||
/* Mask layers don't have an active flag. Do nothing. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
static void actkeys_channel_unset_active(bAnimListElem *ale)
|
||||
{
|
||||
switch (ale->datatype) {
|
||||
case ALE_FCURVE:
|
||||
((FCurve *)ale->key_data)->flag &= ~FCURVE_ACTIVE;
|
||||
break;
|
||||
case ALE_GPFRAME:
|
||||
((bGPDlayer *)ale->data)->flag &= ~GP_LAYER_ACTIVE;
|
||||
ale->update |= ANIM_UPDATE_DEPS;
|
||||
break;
|
||||
case ALE_MASKLAY:
|
||||
/* Mask layers don't have an active flag. Do nothing. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void actkeys_channel_select(bAnimListElem *ale, const eEditKeyframes_Select select_mode)
|
||||
{
|
||||
// GG:TODO: Is this function necessary when (anim_channels_edit.c) anim_channels_select_set()
|
||||
// exists?
|
||||
switch (select_mode) {
|
||||
case SELECT_SUBTRACT: {
|
||||
switch (ale->datatype) {
|
||||
case ALE_FCURVE:
|
||||
((FCurve *)ale->key_data)->flag &= ~FCURVE_SELECTED;
|
||||
break;
|
||||
case ALE_GPFRAME:
|
||||
((bGPDlayer *)ale->data)->flag &= ~GP_LAYER_SELECT;
|
||||
ale->update |= ANIM_UPDATE_DEPS;
|
||||
break;
|
||||
case ALE_MASKLAY:
|
||||
((MaskLayer *)ale->data)->flag &= ~MASK_LAYERFLAG_SELECT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SELECT_ADD: {
|
||||
switch (ale->datatype) {
|
||||
case ALE_FCURVE:
|
||||
((FCurve *)ale->key_data)->flag |= FCURVE_SELECTED;
|
||||
break;
|
||||
case ALE_GPFRAME:
|
||||
((bGPDlayer *)ale->data)->flag |= GP_LAYER_SELECT;
|
||||
ale->update |= ANIM_UPDATE_DEPS;
|
||||
break;
|
||||
case ALE_MASKLAY:
|
||||
((MaskLayer *)ale->data)->flag |= MASK_LAYERFLAG_SELECT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SELECT_INVERT: {
|
||||
switch (ale->datatype) {
|
||||
case ALE_FCURVE:
|
||||
((FCurve *)ale->key_data)->flag ^= FCURVE_SELECTED;
|
||||
break;
|
||||
case ALE_GPFRAME:
|
||||
((bGPDlayer *)ale->data)->flag ^= GP_LAYER_SELECT;
|
||||
ale->update |= ANIM_UPDATE_DEPS;
|
||||
break;
|
||||
case ALE_MASKLAY:
|
||||
((MaskLayer *)ale->data)->flag ^= MASK_LAYERFLAG_SELECT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SELECT_REPLACE: {
|
||||
/* Caller must handle this manually, as SELECT_REPLACE depends more on the situation. */
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void actkeys_channel_set_active_selected_and_update(bAnimContext *ac, bAnimListElem *ale)
|
||||
{
|
||||
|
||||
if (ale == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
actkeys_channel_set_active(ale);
|
||||
actkeys_channel_select(ale, SELECT_ADD);
|
||||
|
||||
ListBase anim_data = {NULL, NULL};
|
||||
BLI_addtail(&anim_data, ale);
|
||||
|
||||
/* GreasePencil Layer might need updated. */
|
||||
ANIM_animdata_update(&ac, &anim_data);
|
||||
ANIM_animdata_freelist(&anim_data);
|
||||
}
|
||||
|
||||
static void actkeys_keyframes_loop_and_select_channel(const short select_mode,
|
||||
KeyframeEditData *ked,
|
||||
bDopeSheet *ads,
|
||||
bAnimListElem *ale,
|
||||
KeyframeEditFunc key_ok,
|
||||
KeyframeEditFunc key_cb,
|
||||
FcuEditFunc fcu_cb)
|
||||
{
|
||||
/* Firstly, check if any keyframes will be hit by this. */
|
||||
if (!ANIM_animchannel_keyframes_loop(ked, ads, ale, NULL, key_ok, fcu_cb)) {
|
||||
return;
|
||||
}
|
||||
|
||||
ANIM_animchannel_keyframes_loop(ked, ads, ale, key_ok, key_cb, fcu_cb);
|
||||
|
||||
switch (ale->datatype) {
|
||||
case ALE_FCURVE: /* F-Curve */
|
||||
{
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
actkeys_select_channel_based_on_keys(fcu, select_mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static bAnimListElem *actkeys_find_list_element_at_position(bAnimContext *ac,
|
||||
int filter,
|
||||
float region_x,
|
||||
@@ -229,6 +379,39 @@ static bool actkeys_is_key_at_position(bAnimContext *ac, float region_x, float r
|
||||
return found;
|
||||
}
|
||||
|
||||
// GG:TODO: exact C+P from graph_utils.c which is from graph_intern.h.....
|
||||
/**
|
||||
* Find 'active' F-Curve.
|
||||
* It must be editable, since that's the purpose of these buttons (subject to change).
|
||||
* We return the 'wrapper' since it contains valuable context info (about hierarchy),
|
||||
* which will need to be freed when the caller is done with it.
|
||||
*
|
||||
* \note curve-visible flag isn't included,
|
||||
* otherwise selecting a curve via list to edit is too cumbersome.
|
||||
*/
|
||||
static bAnimListElem *get_active_channel(bAnimContext *ac)
|
||||
{
|
||||
ListBase anim_data = {NULL, NULL};
|
||||
int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ACTIVE);
|
||||
size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
||||
|
||||
/* We take the first channel only, since some other ones may have had 'active' flag set
|
||||
* if they were from linked data.
|
||||
*/
|
||||
if (items) {
|
||||
bAnimListElem *ale = (bAnimListElem *)anim_data.first;
|
||||
|
||||
/* remove first item from list, then free the rest of the list and return the stored one */
|
||||
BLI_remlink(&anim_data, ale);
|
||||
ANIM_animdata_freelist(&anim_data);
|
||||
|
||||
return ale;
|
||||
}
|
||||
|
||||
/* no active channel */
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* ******************** Deselect All Operator ***************************** */
|
||||
/* This operator works in one of three ways:
|
||||
* 1) (de)select all (AKEY) - test if select all or deselect all
|
||||
@@ -242,7 +425,7 @@ static bool actkeys_is_key_at_position(bAnimContext *ac, float region_x, float r
|
||||
* - test: check if select or deselect all
|
||||
* - sel: how to select keyframes (SELECT_*)
|
||||
*/
|
||||
static void deselect_action_keys(bAnimContext *ac, short test, short sel)
|
||||
static void deselect_action_keys(bAnimContext *ac, short test, short sel, const bool do_channels)
|
||||
{
|
||||
ListBase anim_data = {NULL, NULL};
|
||||
bAnimListElem *ale;
|
||||
@@ -305,6 +488,16 @@ static void deselect_action_keys(bAnimContext *ac, short test, short sel)
|
||||
else {
|
||||
ANIM_fcurve_keyframes_loop(&ked, ale->key_data, NULL, sel_cb, NULL);
|
||||
}
|
||||
|
||||
/* affect channel selection status? */
|
||||
if (do_channels) {
|
||||
/* deactivate the F-Curve, and deselect if deselecting keyframes.
|
||||
* otherwise select the F-Curve too since we've selected all the keyframes
|
||||
*/
|
||||
actkeys_channel_select(ale, sel);
|
||||
/* always deactivate all F-Curves if we perform batch ops for selection */
|
||||
actkeys_channel_unset_active(ale);
|
||||
}
|
||||
}
|
||||
|
||||
/* Cleanup */
|
||||
@@ -323,26 +516,35 @@ static int actkeys_deselectall_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
/* find active F-Curve, and preserve this for later
|
||||
* or else it becomes annoying with the current active
|
||||
* curve keeps fading out even while you're editing it
|
||||
*/
|
||||
bAnimListElem *ale_active = get_active_channel(&ac);
|
||||
/* 'standard' behavior - check if selected, then apply relevant selection */
|
||||
const int action = RNA_enum_get(op->ptr, "action");
|
||||
switch (action) {
|
||||
case SEL_TOGGLE:
|
||||
deselect_action_keys(&ac, 1, SELECT_ADD);
|
||||
deselect_action_keys(&ac, 1, SELECT_ADD, true);
|
||||
break;
|
||||
case SEL_SELECT:
|
||||
deselect_action_keys(&ac, 0, SELECT_ADD);
|
||||
deselect_action_keys(&ac, 0, SELECT_ADD, true);
|
||||
break;
|
||||
case SEL_DESELECT:
|
||||
deselect_action_keys(&ac, 0, SELECT_SUBTRACT);
|
||||
deselect_action_keys(&ac, 0, SELECT_SUBTRACT, true);
|
||||
break;
|
||||
case SEL_INVERT:
|
||||
deselect_action_keys(&ac, 0, SELECT_INVERT);
|
||||
deselect_action_keys(&ac, 0, SELECT_INVERT, true);
|
||||
break;
|
||||
default:
|
||||
BLI_assert(0);
|
||||
break;
|
||||
}
|
||||
|
||||
/* Restore active channel selection. */
|
||||
actkeys_channel_set_active_selected_and_update(&ac, ale_active);
|
||||
ale_active = NULL;
|
||||
|
||||
/* set notifier that keyframe selection have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
||||
if (ac.datatype == ANIMCONT_GPENCIL) {
|
||||
@@ -388,7 +590,8 @@ enum {
|
||||
|
||||
typedef struct BoxSelectData {
|
||||
bAnimContext *ac;
|
||||
short selectmode;
|
||||
short box_selectmode;
|
||||
short key_selectmode;
|
||||
|
||||
KeyframeEditData ked;
|
||||
KeyframeEditFunc ok_cb, select_cb;
|
||||
@@ -405,14 +608,27 @@ static void box_select_elem(
|
||||
bGPdata *gpd = ale->data;
|
||||
bGPDlayer *gpl;
|
||||
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
ED_gpencil_layer_frames_select_box(gpl, xmin, xmax, data->selectmode);
|
||||
ED_gpencil_layer_frames_select_box(gpl, xmin, xmax, data->key_selectmode);
|
||||
}
|
||||
ale->update |= ANIM_UPDATE_DEPS;
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
case ANIMTYPE_GPLAYER: {
|
||||
ED_gpencil_layer_frames_select_box(ale->data, xmin, xmax, sel_data->selectmode);
|
||||
|
||||
if (ELEM(
|
||||
sel_data->box_selectmode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) {
|
||||
ED_gpencil_layer_frames_select_box(ale->data, xmin, xmax, sel_data->key_selectmode);
|
||||
}
|
||||
else if (ELEM(sel_data->box_selectmode, ACTKEYS_BORDERSEL_CHANNELS)) {
|
||||
ED_gpencil_select_frames(ale->data, sel_data->key_selectmode);
|
||||
}
|
||||
else {
|
||||
BLI_assert(!"Unknown Box select mode not implemented");
|
||||
}
|
||||
if (!summary) {
|
||||
ED_gpencil_select_layer_based_on_frames(ale->data);
|
||||
}
|
||||
ale->update |= ANIM_UPDATE_DEPS;
|
||||
break;
|
||||
}
|
||||
@@ -420,12 +636,38 @@ static void box_select_elem(
|
||||
Mask *mask = ale->data;
|
||||
MaskLayer *masklay;
|
||||
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
|
||||
ED_masklayer_frames_select_box(masklay, xmin, xmax, sel_data->selectmode);
|
||||
|
||||
if (ELEM(sel_data->box_selectmode,
|
||||
ACTKEYS_BORDERSEL_FRAMERANGE,
|
||||
ACTKEYS_BORDERSEL_ALLKEYS)) {
|
||||
ED_masklayer_frames_select_box(masklay, xmin, xmax, sel_data->key_selectmode);
|
||||
}
|
||||
else if (ELEM(sel_data->box_selectmode, ACTKEYS_BORDERSEL_CHANNELS)) {
|
||||
ED_mask_select_frames(masklay, sel_data->key_selectmode);
|
||||
}
|
||||
else {
|
||||
BLI_assert(!"Unknown Box select mode not implemented");
|
||||
}
|
||||
if (!summary) {
|
||||
ED_mask_select_layer_based_on_frames(masklay);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_MASKLAYER: {
|
||||
ED_masklayer_frames_select_box(ale->data, xmin, xmax, sel_data->selectmode);
|
||||
if (ELEM(
|
||||
sel_data->box_selectmode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) {
|
||||
ED_masklayer_frames_select_box(ale->data, xmin, xmax, sel_data->key_selectmode);
|
||||
}
|
||||
else if (ELEM(sel_data->box_selectmode, ACTKEYS_BORDERSEL_CHANNELS)) {
|
||||
ED_mask_select_frames(ale->data, sel_data->key_selectmode);
|
||||
}
|
||||
else {
|
||||
BLI_assert(!"Unknown Box select mode not implemented");
|
||||
}
|
||||
if (!summary) {
|
||||
ED_mask_select_layer_based_on_frames(ale->data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -445,19 +687,28 @@ static void box_select_elem(
|
||||
ANIM_animdata_freelist(&anim_data);
|
||||
}
|
||||
|
||||
ANIM_animchannel_keyframes_loop(
|
||||
&sel_data->ked, ac->ads, ale, sel_data->ok_cb, sel_data->select_cb, NULL);
|
||||
actkeys_keyframes_loop_and_select_channel(sel_data->key_selectmode,
|
||||
&sel_data->ked,
|
||||
ac->ads,
|
||||
ale,
|
||||
sel_data->ok_cb,
|
||||
sel_data->select_cb,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void box_select_action(bAnimContext *ac, const rcti rect, short mode, short selectmode)
|
||||
static void box_select_action(bAnimContext *ac,
|
||||
const rcti rect,
|
||||
short box_selectmode,
|
||||
short key_selectmode)
|
||||
{
|
||||
ListBase anim_data = {NULL, NULL};
|
||||
bAnimListElem *ale;
|
||||
int filter;
|
||||
|
||||
BoxSelectData sel_data = {.ac = ac, .selectmode = selectmode};
|
||||
BoxSelectData sel_data = {
|
||||
.ac = ac, .key_selectmode = key_selectmode, .box_selectmode = box_selectmode};
|
||||
View2D *v2d = &ac->region->v2d;
|
||||
rctf rectf;
|
||||
|
||||
@@ -471,13 +722,14 @@ static void box_select_action(bAnimContext *ac, const rcti rect, short mode, sho
|
||||
ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
|
||||
|
||||
/* get beztriple editing/validation funcs */
|
||||
sel_data.select_cb = ANIM_editkeyframes_select(selectmode);
|
||||
sel_data.select_cb = ANIM_editkeyframes_select(key_selectmode);
|
||||
|
||||
if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) {
|
||||
if (ELEM(box_selectmode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) {
|
||||
sel_data.ok_cb = ANIM_editkeyframes_ok(BEZT_OK_FRAMERANGE);
|
||||
}
|
||||
else {
|
||||
sel_data.ok_cb = NULL;
|
||||
/* ACTKEYS_BORDERSEL_CHANNELS */
|
||||
sel_data.ok_cb = ANIM_editkeyframes_ok(BEZT_OK_ALL_ARE_VALID);
|
||||
}
|
||||
|
||||
/* init editing data */
|
||||
@@ -493,7 +745,7 @@ static void box_select_action(bAnimContext *ac, const rcti rect, short mode, sho
|
||||
float ymin = ymax - ACHANNEL_STEP(ac);
|
||||
|
||||
/* set horizontal range (if applicable) */
|
||||
if (ELEM(mode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) {
|
||||
if (ELEM(box_selectmode, ACTKEYS_BORDERSEL_FRAMERANGE, ACTKEYS_BORDERSEL_ALLKEYS)) {
|
||||
/* if channel is mapped in NLA, apply correction */
|
||||
if (adt) {
|
||||
sel_data.ked.iterflags &= ~(KED_F1_NLA_UNMAP | KED_F2_NLA_UNMAP);
|
||||
@@ -508,7 +760,8 @@ static void box_select_action(bAnimContext *ac, const rcti rect, short mode, sho
|
||||
}
|
||||
|
||||
/* perform vertical suitability check (if applicable) */
|
||||
if ((mode == ACTKEYS_BORDERSEL_FRAMERANGE) || !((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
|
||||
if ((box_selectmode == ACTKEYS_BORDERSEL_FRAMERANGE) ||
|
||||
!((ymax < rectf.ymin) || (ymin > rectf.ymax))) {
|
||||
box_select_elem(&sel_data, ale, rectf.xmin, rectf.xmax, false);
|
||||
}
|
||||
}
|
||||
@@ -546,10 +799,11 @@ static int actkeys_box_select_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
bAnimListElem *ale_active = get_active_channel(&ac);
|
||||
const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
|
||||
const int selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
|
||||
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
|
||||
deselect_action_keys(&ac, 1, SELECT_SUBTRACT);
|
||||
deselect_action_keys(&ac, 1, SELECT_SUBTRACT, true);
|
||||
}
|
||||
|
||||
/* get settings from operator */
|
||||
@@ -578,6 +832,10 @@ static int actkeys_box_select_exec(bContext *C, wmOperator *op)
|
||||
/* apply box_select action */
|
||||
box_select_action(&ac, rect, mode, selectmode);
|
||||
|
||||
/* Restore active channel selection. */
|
||||
actkeys_channel_set_active_selected_and_update(&ac, ale_active);
|
||||
ale_active = NULL;
|
||||
|
||||
/* set notifier that keyframe selection have changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
||||
if (ac.datatype == ANIMCONT_GPENCIL) {
|
||||
@@ -641,7 +899,7 @@ static void region_select_elem(RegionSelectData *sel_data, bAnimListElem *ale, b
|
||||
bGPdata *gpd = ale->data;
|
||||
bGPDlayer *gpl;
|
||||
for (gpl = gpd->layers.first; gpl; gpl = gpl->next) {
|
||||
ED_gpencil_layer_frames_select_region(&rdata->ked, ale->data, rdata->mode, rdata->selectmode);
|
||||
ED_gpencil_layer_frames_select_region(&rdata->ked, ale->data, rdata->mode, rdata->key_selectmode);
|
||||
}
|
||||
break;
|
||||
}
|
||||
@@ -649,6 +907,11 @@ static void region_select_elem(RegionSelectData *sel_data, bAnimListElem *ale, b
|
||||
case ANIMTYPE_GPLAYER: {
|
||||
ED_gpencil_layer_frames_select_region(
|
||||
&sel_data->ked, ale->data, sel_data->mode, sel_data->selectmode);
|
||||
|
||||
if (!summary) {
|
||||
ED_gpencil_select_layer_based_on_frames(ale->data);
|
||||
}
|
||||
|
||||
ale->update |= ANIM_UPDATE_DEPS;
|
||||
break;
|
||||
}
|
||||
@@ -658,12 +921,18 @@ static void region_select_elem(RegionSelectData *sel_data, bAnimListElem *ale, b
|
||||
for (masklay = mask->masklayers.first; masklay; masklay = masklay->next) {
|
||||
ED_masklayer_frames_select_region(
|
||||
&sel_data->ked, masklay, sel_data->mode, sel_data->selectmode);
|
||||
if (!summary) {
|
||||
ED_mask_select_layer_based_on_frames(masklay);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ANIMTYPE_MASKLAYER: {
|
||||
ED_masklayer_frames_select_region(
|
||||
&sel_data->ked, ale->data, sel_data->mode, sel_data->selectmode);
|
||||
if (!summary) {
|
||||
ED_mask_select_layer_based_on_frames(ale->data);
|
||||
}
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
@@ -683,8 +952,13 @@ static void region_select_elem(RegionSelectData *sel_data, bAnimListElem *ale, b
|
||||
ANIM_animdata_freelist(&anim_data);
|
||||
}
|
||||
|
||||
ANIM_animchannel_keyframes_loop(
|
||||
&sel_data->ked, ac->ads, ale, sel_data->ok_cb, sel_data->select_cb, NULL);
|
||||
actkeys_keyframes_loop_and_select_channel(sel_data->selectmode,
|
||||
&sel_data->ked,
|
||||
ac->ads,
|
||||
ale,
|
||||
sel_data->ok_cb,
|
||||
sel_data->select_cb,
|
||||
NULL);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -798,10 +1072,12 @@ static int actkeys_lassoselect_exec(bContext *C, wmOperator *op)
|
||||
return OPERATOR_CANCELLED;
|
||||
}
|
||||
|
||||
bAnimListElem *ale_active = get_active_channel(&ac);
|
||||
|
||||
const eSelectOp sel_op = RNA_enum_get(op->ptr, "mode");
|
||||
const int selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
|
||||
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
|
||||
deselect_action_keys(&ac, 1, SELECT_SUBTRACT);
|
||||
deselect_action_keys(&ac, 1, SELECT_SUBTRACT, true);
|
||||
}
|
||||
|
||||
/* get settings from operator */
|
||||
@@ -813,6 +1089,10 @@ static int actkeys_lassoselect_exec(bContext *C, wmOperator *op)
|
||||
|
||||
MEM_freeN((void *)data_lasso.mcoords);
|
||||
|
||||
/* Restore active channel selection. */
|
||||
actkeys_channel_set_active_selected_and_update(&ac, ale_active);
|
||||
ale_active = NULL;
|
||||
|
||||
/* send notifier that keyframe selection has changed */
|
||||
WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_SELECTED, NULL);
|
||||
if (ac.datatype == ANIMCONT_GPENCIL) {
|
||||
@@ -865,7 +1145,7 @@ static int action_circle_select_exec(bContext *C, wmOperator *op)
|
||||
WM_gesture_is_modal_first(op->customdata));
|
||||
const short selectmode = (sel_op != SEL_OP_SUB) ? SELECT_ADD : SELECT_SUBTRACT;
|
||||
if (SEL_OP_USE_PRE_DESELECT(sel_op)) {
|
||||
deselect_action_keys(&ac, 0, SELECT_SUBTRACT);
|
||||
deselect_action_keys(&ac, 0, SELECT_SUBTRACT, true);
|
||||
}
|
||||
|
||||
data.mval[0] = x;
|
||||
@@ -1349,7 +1629,7 @@ static void actkeys_select_leftright(bAnimContext *ac, short leftright, short se
|
||||
/* - 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
|
||||
*/
|
||||
deselect_action_keys(ac, 0, SELECT_SUBTRACT);
|
||||
deselect_action_keys(ac, 0, SELECT_SUBTRACT, false);
|
||||
}
|
||||
|
||||
/* set callbacks and editing data */
|
||||
@@ -1545,10 +1825,12 @@ static void actkeys_mselect_single(bAnimContext *ac,
|
||||
/* select the nominated keyframe on the given frame */
|
||||
if (ale->type == ANIMTYPE_GPLAYER) {
|
||||
ED_gpencil_select_frame(ale->data, selx, select_mode);
|
||||
ED_gpencil_select_layer_based_on_frames(ale->data);
|
||||
ale->update |= ANIM_UPDATE_DEPS;
|
||||
}
|
||||
else if (ale->type == ANIMTYPE_MASKLAYER) {
|
||||
ED_mask_select_frame(ale->data, selx, select_mode);
|
||||
ED_mask_select_layer_based_on_frames(ale->data);
|
||||
}
|
||||
else {
|
||||
if (ELEM(ac->datatype, ANIMCONT_GPENCIL, ANIMCONT_MASK) && (ale->type == ANIMTYPE_SUMMARY) &&
|
||||
@@ -1574,7 +1856,46 @@ static void actkeys_mselect_single(bAnimContext *ac,
|
||||
ANIM_animdata_freelist(&anim_data);
|
||||
}
|
||||
else {
|
||||
|
||||
// Question: Wayde Moss : Which block to use?
|
||||
#if 1
|
||||
// This block is inconsistent with how the graph editor does channel selection but feels
|
||||
// better.
|
||||
ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL);
|
||||
|
||||
switch (ale->datatype) {
|
||||
case ALE_FCURVE: /* F-Curve */
|
||||
{
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
actkeys_select_channel_based_on_keys(fcu, select_mode);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
// This block is consistent with how the graph editor does channel selection but feels wrong.
|
||||
|
||||
if (!ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, NULL, ok_cb, NULL)) {
|
||||
return;
|
||||
}
|
||||
const int selected_index = ked.curIndex;
|
||||
|
||||
ANIM_animchannel_keyframes_loop(&ked, ac->ads, ale, ok_cb, select_cb, NULL);
|
||||
|
||||
switch (ale->datatype) {
|
||||
case ALE_FCURVE: /* F-Curve */
|
||||
{
|
||||
FCurve *fcu = (FCurve *)ale->key_data;
|
||||
BezTriple *selected_bezt = fcu->bezt + selected_index;
|
||||
|
||||
if (BEZT_ISSEL_ANY(selected_bezt)) {
|
||||
fcu->flag |= FCURVE_SELECTED;
|
||||
}
|
||||
else {
|
||||
fcu->flag &= ~FCURVE_SELECTED;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1725,7 +2046,7 @@ static int mouse_action_keys(bAnimContext *ac,
|
||||
}
|
||||
else {
|
||||
/* deselect all keyframes */
|
||||
deselect_action_keys(ac, 0, SELECT_SUBTRACT);
|
||||
deselect_action_keys(ac, 0, SELECT_SUBTRACT, true);
|
||||
|
||||
/* highlight channel clicked on */
|
||||
if (ELEM(ac->datatype, ANIMCONT_ACTION, ANIMCONT_DOPESHEET, ANIMCONT_TIMELINE)) {
|
||||
|
Reference in New Issue
Block a user