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

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBastien Montagne <montagne29@wanadoo.fr>2014-03-14 15:45:22 +0400
committerBastien Montagne <montagne29@wanadoo.fr>2014-03-14 15:48:15 +0400
commit1f3655d224196129fc6daf20e678199b95321bff (patch)
tree30ca82ce747f1634bdc1ccfb1b9fe26aecfbed30 /source/blender/editors/animation/anim_channels_edit.c
parentade6646755224ce9178d280738727c1a968b28b6 (diff)
Fix T38897: Problems moving animation channels up and down in dope sheet/action editor.
Basic idea is to check whether an element is visible or not, and ignore those that are hidden, during move up/down. Reviewers: aligorith Reviewed By: aligorith Differential Revision: https://developer.blender.org/D376
Diffstat (limited to 'source/blender/editors/animation/anim_channels_edit.c')
-rw-r--r--source/blender/editors/animation/anim_channels_edit.c89
1 files changed, 74 insertions, 15 deletions
diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index ee8b5dcee67..eb9881aa0b6 100644
--- a/source/blender/editors/animation/anim_channels_edit.c
+++ b/source/blender/editors/animation/anim_channels_edit.c
@@ -36,6 +36,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_listbase.h"
#include "BKE_library.h"
#include "DNA_anim_types.h"
@@ -653,7 +654,8 @@ typedef struct tReorderChannelIsland {
typedef enum eReorderIslandFlag {
REORDER_ISLAND_SELECTED = (1 << 0), /* island is selected */
REORDER_ISLAND_UNTOUCHABLE = (1 << 1), /* island should be ignored */
- REORDER_ISLAND_MOVED = (1 << 2) /* island has already been moved */
+ REORDER_ISLAND_MOVED = (1 << 2), /* island has already been moved */
+ REORDER_ISLAND_HIDDEN = (1 << 3), /* island is not visible */
} eReorderIslandFlag;
@@ -691,7 +693,12 @@ static bool rearrange_island_up(ListBase *list, tReorderChannelIsland *island)
if (rearrange_island_ok(island)) {
/* moving up = moving before the previous island, otherwise we're in the same place */
tReorderChannelIsland *prev = island->prev;
-
+
+ /* Skip hidden islands! */
+ while (prev && prev->flag & REORDER_ISLAND_HIDDEN) {
+ prev = prev->prev;
+ }
+
if (prev) {
/* remove from current position */
BLI_remlink(list, island);
@@ -711,7 +718,12 @@ static bool rearrange_island_down(ListBase *list, tReorderChannelIsland *island)
if (rearrange_island_ok(island)) {
/* moving down = moving after the next island, otherwise we're in the same place */
tReorderChannelIsland *next = island->next;
-
+
+ /* Skip hidden islands! */
+ while (next && next->flag & REORDER_ISLAND_HIDDEN) {
+ next = next->next;
+ }
+
if (next) {
/* can only move past if next is not untouchable (i.e. nothing can go after it) */
if ((next->flag & REORDER_ISLAND_UNTOUCHABLE) == 0) {
@@ -784,7 +796,7 @@ static AnimChanRearrangeFp rearrange_get_mode_func(short mode)
/* Rearrange Islands Generics ------------------------------------- */
/* add channel into list of islands */
-static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *srcList, Link *channel, short type)
+static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *srcList, Link *channel, short type, const bool is_hidden)
{
tReorderChannelIsland *island = islands->last; /* always try to add to last island if possible */
bool is_sel = false, is_untouchable = false;
@@ -819,9 +831,15 @@ static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *sr
}
/* do we need to add to a new island? */
- if ((island == NULL) || /* 1) no islands yet */
- ((island->flag & REORDER_ISLAND_SELECTED) == 0) || /* 2) unselected islands have single channels only - to allow up/down movement */
- (is_sel == 0)) /* 3) if channel is unselected, stop existing island (it was either wrong sel status, or full already) */
+ if (/* 1) no islands yet */
+ (island == NULL) ||
+ /* 2) unselected islands have single channels only - to allow up/down movement */
+ ((island->flag & REORDER_ISLAND_SELECTED) == 0) ||
+ /* 3) if channel is unselected, stop existing island (it was either wrong sel status, or full already) */
+ (is_sel == 0) ||
+ /* 4) hidden status changes */
+ ((island->flag & REORDER_ISLAND_HIDDEN) != is_hidden)
+ )
{
/* create a new island now */
island = MEM_callocN(sizeof(tReorderChannelIsland), "tReorderChannelIsland");
@@ -831,6 +849,8 @@ static void rearrange_animchannel_add_to_islands(ListBase *islands, ListBase *sr
island->flag |= REORDER_ISLAND_SELECTED;
if (is_untouchable)
island->flag |= REORDER_ISLAND_UNTOUCHABLE;
+ if (is_hidden)
+ island->flag |= REORDER_ISLAND_HIDDEN;
}
/* add channel to island - need to remove it from its existing list first though */
@@ -858,8 +878,16 @@ static void rearrange_animchannel_flatten_islands(ListBase *islands, ListBase *s
/* ............................. */
+static void rearrange_animchannels_filter_visible(ListBase *anim_data_visible, bAnimContext *ac, short type)
+{
+ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+
+ ANIM_animdata_filter(ac, anim_data_visible, filter, ac->data, type);
+}
+
/* performing rearranging of channels using islands */
-static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp rearrange_func, short mode, short type)
+static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp rearrange_func,
+ short mode, short type, ListBase *anim_data_visible)
{
ListBase islands = {NULL, NULL};
Link *channel, *chanNext = NULL;
@@ -871,8 +899,10 @@ static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp re
/* group channels into islands */
for (channel = list->first; channel; channel = chanNext) {
+ /* find out whether this channel is present in anim_data_visible or not! */
+ const bool is_hidden = (BLI_findptr(anim_data_visible, channel, offsetof(bAnimListElem, data)) == NULL);
chanNext = channel->next;
- rearrange_animchannel_add_to_islands(&islands, list, channel, type);
+ rearrange_animchannel_add_to_islands(&islands, list, channel, type, is_hidden);
}
/* perform moving of selected islands now, but only if there is more than one of 'em so that something will happen
@@ -907,9 +937,10 @@ static bool rearrange_animchannel_islands(ListBase *list, AnimChanRearrangeFp re
* ! NLA tracks are displayed in opposite order, so directions need care
* mode: REARRANGE_ANIMCHAN_*
*/
-static void rearrange_nla_channels(bAnimContext *UNUSED(ac), AnimData *adt, short mode)
+static void rearrange_nla_channels(bAnimContext *ac, AnimData *adt, short mode)
{
AnimChanRearrangeFp rearrange_func;
+ ListBase anim_data_visible = {NULL, NULL};
/* hack: invert mode so that functions will work in right order */
mode *= -1;
@@ -923,8 +954,14 @@ static void rearrange_nla_channels(bAnimContext *UNUSED(ac), AnimData *adt, shor
//if (EXPANDED_DRVD(adt) == 0)
// return;
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_NLATRACK);
+
/* perform rearranging on tracks list */
- rearrange_animchannel_islands(&adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK);
+ rearrange_animchannel_islands(&adt->nla_tracks, rearrange_func, mode, ANIMTYPE_NLATRACK, &anim_data_visible);
+
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
}
/* Drivers Specific Stuff ------------------------------------------------- */
@@ -932,10 +969,11 @@ static void rearrange_nla_channels(bAnimContext *UNUSED(ac), AnimData *adt, shor
/* Change the order drivers within AnimData block
* mode: REARRANGE_ANIMCHAN_*
*/
-static void rearrange_driver_channels(bAnimContext *UNUSED(ac), AnimData *adt, short mode)
+static void rearrange_driver_channels(bAnimContext *ac, AnimData *adt, short mode)
{
/* get rearranging function */
AnimChanRearrangeFp rearrange_func = rearrange_get_mode_func(mode);
+ ListBase anim_data_visible = {NULL, NULL};
if (rearrange_func == NULL)
return;
@@ -944,8 +982,14 @@ static void rearrange_driver_channels(bAnimContext *UNUSED(ac), AnimData *adt, s
if (EXPANDED_DRVD(adt) == 0)
return;
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
+
/* perform rearranging on drivers list (drivers are really just F-Curves) */
- rearrange_animchannel_islands(&adt->drivers, rearrange_func, mode, ANIMTYPE_FCURVE);
+ rearrange_animchannel_islands(&adt->drivers, rearrange_func, mode, ANIMTYPE_FCURVE, &anim_data_visible);
+
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
}
/* Action Specific Stuff ------------------------------------------------- */
@@ -1027,6 +1071,7 @@ static void join_groups_action_temp(bAction *act)
static void rearrange_action_channels(bAnimContext *ac, bAction *act, short mode)
{
bActionGroup tgrp;
+ ListBase anim_data_visible = {NULL, NULL};
bool do_channels;
/* get rearranging function */
@@ -1038,21 +1083,35 @@ static void rearrange_action_channels(bAnimContext *ac, bAction *act, short mode
/* make sure we're only operating with groups (vs a mixture of groups+curves) */
split_groups_action_temp(act, &tgrp);
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_GROUP);
+
/* rearrange groups first
* - the group's channels will only get considered if nothing happened when rearranging the groups
* i.e. the rearrange function returned 0
*/
- do_channels = rearrange_animchannel_islands(&act->groups, rearrange_func, mode, ANIMTYPE_GROUP) == 0;
+ do_channels = (rearrange_animchannel_islands(&act->groups, rearrange_func, mode, ANIMTYPE_GROUP,
+ &anim_data_visible) == 0);
+
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
if (do_channels) {
bActionGroup *agrp;
+ /* Filter visible data. */
+ rearrange_animchannels_filter_visible(&anim_data_visible, ac, ANIMTYPE_FCURVE);
+
for (agrp = act->groups.first; agrp; agrp = agrp->next) {
/* only consider F-Curves if they're visible (group expanded) */
if (EXPANDED_AGRP(ac, agrp)) {
- rearrange_animchannel_islands(&agrp->channels, rearrange_func, mode, ANIMTYPE_FCURVE);
+ rearrange_animchannel_islands(&agrp->channels, rearrange_func, mode, ANIMTYPE_FCURVE,
+ &anim_data_visible);
}
}
+
+ /* free temp data */
+ BLI_freelistN(&anim_data_visible);
}
/* assemble lists into one list (and clear moved tags) */