[Bf-blender-cvs] [1f3655d] master: Fix T38897: Problems moving animation channels up and down in dope sheet/action editor.

Bastien Montagne noreply at git.blender.org
Fri Mar 14 12:50:33 CET 2014


Commit: 1f3655d224196129fc6daf20e678199b95321bff
Author: Bastien Montagne
Date:   Fri Mar 14 12:45:22 2014 +0100
https://developer.blender.org/rB1f3655d224196129fc6daf20e678199b95321bff

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

===================================================================

M	source/blender/editors/animation/anim_channels_edit.c

===================================================================

diff --git a/source/blender/editors/animation/anim_channels_edit.c b/source/blender/editors/animation/anim_channels_edit.c
index ee8b5dc..eb9881a 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) */




More information about the Bf-blender-cvs mailing list