[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [23931] trunk/blender/source/blender/ editors: Graph Editor: Visibility toggles improved (Durian Request)

Joshua Leung aligorith at gmail.com
Mon Oct 19 04:18:05 CEST 2009


Revision: 23931
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=23931
Author:   aligorith
Date:     2009-10-19 04:17:57 +0200 (Mon, 19 Oct 2009)

Log Message:
-----------
Graph Editor: Visibility toggles improved (Durian Request)

Toggling one of the visibility toggles in the Graph Editor now flushes the new value up/down the hierarchy. 
- when enabling a visibility toggle, all the 'higher' up and lower down channels get their visibility turned on
- when disabling a visibility toggle, only the ones lower down get their visibility turned off (since there might still be other channels at the same level which are still enabled.

This makes showing/hiding groups of F-Curves much easier, since previously you'd have to use multiple clicks to isolate particular F-Curves. For example, to isolate only X Location curves, previously, the workflow would have been to select all AKEY, hide all VKEY, then toggle the individual X Location curves in group, then make sure the groups and objects, etc. were also visible. Now, the steps of making sure that the parents were visible too has been eliminated.


---

Also, fixed a few minor bugs with the animation-backend code for Graph Editor. 

Modified Paths:
--------------
    trunk/blender/source/blender/editors/animation/anim_channels_defines.c
    trunk/blender/source/blender/editors/animation/anim_channels_edit.c
    trunk/blender/source/blender/editors/animation/anim_filter.c
    trunk/blender/source/blender/editors/space_graph/space_graph.c

Modified: trunk/blender/source/blender/editors/animation/anim_channels_defines.c
===================================================================
--- trunk/blender/source/blender/editors/animation/anim_channels_defines.c	2009-10-18 23:23:41 UTC (rev 23930)
+++ trunk/blender/source/blender/editors/animation/anim_channels_defines.c	2009-10-19 02:17:57 UTC (rev 23931)
@@ -2258,6 +2258,132 @@
 	WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
 }
 
+/* callback for visiblility-toggle widget settings - perform value flushing (Graph Editor only) */
+static void achannel_setting_visible_widget_cb(bContext *C, void *ale_npoin, void *dummy_poin)
+{
+	bAnimListElem *ale_setting= (bAnimListElem *)ale_npoin;
+	int prevLevel=0, matchLevel=0;
+	short vizOn = 0;
+	
+	bAnimContext ac;
+	ListBase anim_data = {NULL, NULL};
+	bAnimListElem *ale, *match=NULL;
+	int filter;
+	
+	/* send notifiers before doing anything else... */
+	WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL);
+	
+	/* verify animation context */
+	if (ANIM_animdata_get_context(C, &ac) == 0)
+		return;
+	
+	/* verify that we have a channel to operate on, and that it has all we need */
+	if (ale_setting) {
+		/* check if the setting is on... */
+		vizOn= ANIM_channel_setting_get(&ac, ale_setting, ACHANNEL_SETTING_VISIBLE);
+		
+		/* vizOn == -1 means setting not found... */
+		if (vizOn == -1)
+			return;
+	}
+	else
+		return;
+	
+	/* get all channels that can possibly be chosen 
+	 *	- therefore, the filter is simply ANIMFILTER_CHANNELS, since if we took VISIBLE too,
+	 *	  then the channels under closed expanders get ignored...
+	 */
+	filter= ANIMFILTER_CHANNELS;
+	ANIM_animdata_filter(&ac, &anim_data, filter, ac.data, ac.datatype);
+	
+	/* find the channel that got changed */
+	for (ale= anim_data.first; ale; ale= ale->next) {
+		/* compare data, type, and owner/id info */
+		if ((ale->data == ale_setting->data) && (ale->type == ale_setting->type)) {
+			//if (ale->id == ale_setting->id) {
+				match= ale;
+				break;
+			//}
+		}
+	}
+	if (match == NULL) {
+		printf("ERROR: no channel matching the one changed was found \n");
+		BLI_freelistN(&anim_data);
+		return;
+	}
+	else {
+		bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale_setting);
+		
+		/* get the level of the channel that was affected
+		 * 	 - we define the level as simply being the offset for the start of the channel
+		 */
+		matchLevel= (acf->get_offset)? acf->get_offset(&ac, ale_setting) : 0;
+	}
+	
+	/* flush up? 
+	 *	- only flush up if the current state is now enabled 
+	 *	  (otherwise, it's too much work to force the parents to be inactive too)
+	 */
+	if (vizOn) {
+		/* go backwards in the list, until the highest-ranking element (by indention has been covered) */
+		for (ale= match->prev; ale; ale= ale->prev) {
+			bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
+			int level;
+			
+			/* get the level of the current channel traversed 
+			 * 	 - we define the level as simply being the offset for the start of the channel
+			 */
+			level= (acf->get_offset)? acf->get_offset(&ac, ale) : 0;
+			
+			/* if the level is 'less than' (i.e. more important) the previous channel, 
+			 * flush the new status...
+			 */
+			if (level < matchLevel)
+				ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, vizOn);
+			/* however, if the level is 'greater than' (i.e. less important than the previous channel,
+			 * stop searching, since we've already reached the bottom of another hierarchy
+			 */
+			else if (level > matchLevel)
+				break;
+			
+			/* store this level as the 'old' level now */
+			prevLevel= level;
+		}
+	}
+	
+	/* flush down (always) */
+	{
+		/* go forwards in the list, until the lowest-ranking element (by indention has been covered) */
+		for (ale= match->next; ale; ale= ale->next) {
+			bAnimChannelType *acf= ANIM_channel_get_typeinfo(ale);
+			int level;
+			
+			/* get the level of the current channel traversed 
+			 * 	 - we define the level as simply being the offset for the start of the channel
+			 */
+			level= (acf->get_offset)? acf->get_offset(&ac, ale) : 0;
+			
+			/* if the level is 'greater than' (i.e. less important) the channel that was changed, 
+			 * flush the new status...
+			 */
+			if (level > matchLevel)
+				ANIM_channel_setting_set(&ac, ale, ACHANNEL_SETTING_VISIBLE, vizOn);
+			/* however, if the level is 'less than or equal to' the channel that was changed,
+			 * (i.e. the current channel is as important if not more important than the changed channel)
+			 * then we should stop, since we've found the last one of the children we should flush
+			 */
+			else
+				break;
+			
+			/* store this level as the 'old' level now */
+			prevLevel= level;
+		}
+	}
+	
+	/* free temp data */
+	BLI_freelistN(&anim_data);
+}
+
 /* callback for widget sliders - insert keyframes */
 static void achannel_setting_slider_cb(bContext *C, void *id_poin, void *fcu_poin)
 {
@@ -2373,9 +2499,9 @@
 			icon= ICON_CHECKBOX_DEHLT;
 			
 			if (ale->type == ANIMTYPE_FCURVE)
-				tooltip= "F-Curve is visible in Graph Editor for editing.";
+				tooltip= "Channel is visible in Graph Editor for editing.";
 			else
-				tooltip= "F-Curve(s) are visible in Graph Editor for editing.";
+				tooltip= "Channel(s) are visible in Graph Editor for editing.";
 			break;
 			
 		case ACHANNEL_SETTING_EXPAND: /* expanded triangle */
@@ -2440,10 +2566,15 @@
 				break;
 		}
 		
-		/* set call to send relevant notifiers */
-		// NOTE: for now, we only need to send 'edited' 
-		if (but)
-			uiButSetFunc(but, achannel_setting_widget_cb, NULL, NULL);
+		/* set call to send relevant notifiers and/or perform type-specific updates */
+		// TODO: for 'visible' toggles, use the 'N' version of this, storing a duplicate copy of the ale that this uses
+		if (but) {
+			/* 'visibility' toggles for Graph Editor need special flushing */
+			if (setting == ACHANNEL_SETTING_VISIBLE) 
+				uiButSetNFunc(but, achannel_setting_visible_widget_cb, MEM_dupallocN(ale), /*SET_INT_IN_POINTER(...)*/0);
+			else
+				uiButSetFunc(but, achannel_setting_widget_cb, NULL, NULL);
+		}
 	}
 }
 

Modified: trunk/blender/source/blender/editors/animation/anim_channels_edit.c
===================================================================
--- trunk/blender/source/blender/editors/animation/anim_channels_edit.c	2009-10-18 23:23:41 UTC (rev 23930)
+++ trunk/blender/source/blender/editors/animation/anim_channels_edit.c	2009-10-19 02:17:57 UTC (rev 23931)
@@ -1358,7 +1358,7 @@
 	/* get the channel that was clicked on */
 		/* filter channels */
 	filter= (ANIMFILTER_VISIBLE | ANIMFILTER_CHANNELS);
-	filter= ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+	ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
 	
 		/* get channel from index */
 	ale= BLI_findlink(&anim_data, channel_index);

Modified: trunk/blender/source/blender/editors/animation/anim_filter.c
===================================================================
--- trunk/blender/source/blender/editors/animation/anim_filter.c	2009-10-18 23:23:41 UTC (rev 23930)
+++ trunk/blender/source/blender/editors/animation/anim_filter.c	2009-10-19 02:17:57 UTC (rev 23931)
@@ -208,8 +208,10 @@
 static short graphedit_get_context (bAnimContext *ac, SpaceIpo *sipo)
 {
 	/* init dopesheet data if non-existant (i.e. for old files) */
-	if (sipo->ads == NULL)
+	if (sipo->ads == NULL) {
 		sipo->ads= MEM_callocN(sizeof(bDopeSheet), "GraphEdit DopeSheet");
+		sipo->ads->source= (ID *)ac->scene;
+	}
 	
 	/* set settings for Graph Editor - "Selected = Editable" */
 	if (sipo->flag & SIPO_SELCUVERTSONLY)
@@ -1102,7 +1104,7 @@
 			}
 			
 			/* add material's animation data */
-			if (FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_CURVESONLY)) {
+			if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_MAT_OBJD(ma) || (filter_mode & ANIMFILTER_CURVESONLY)) {
 				ANIMDATA_FILTER_CASES(ma, 
 					{ /* AnimData blocks - do nothing... */ },
 					items += animdata_filter_nla(anim_data, ads, ma->adt, filter_mode, ma, ANIMTYPE_DSMAT, (ID *)ma);, 
@@ -1162,7 +1164,7 @@
 				}
 			}
 			
-			if (FILTER_PART_OBJD(psys->part) || (filter_mode & ANIMFILTER_CURVESONLY)) {
+			if (!(filter_mode & ANIMFILTER_VISIBLE) || FILTER_PART_OBJD(psys->part) || (filter_mode & ANIMFILTER_CURVESONLY)) {
 				ANIMDATA_FILTER_CASES(psys->part,
 					{ /* AnimData blocks - do nothing... */ },
 					items += animdata_filter_nla(anim_data, ads, psys->part->adt, filter_mode, psys->part, ANIMTYPE_DSPART, (ID *)psys->part);, 
@@ -1243,7 +1245,7 @@
 	}
 	
 	/* add object-data animation channels? */
-	if ((expanded) || (filter_mode & ANIMFILTER_CURVESONLY)) {
+	if (!(filter_mode & ANIMFILTER_VISIBLE) || (expanded) || (filter_mode & ANIMFILTER_CURVESONLY)) {
 		/* filtering for channels - nla, drivers, keyframes */
 		ANIMDATA_FILTER_CASES(iat, 
 			{ /* AnimData blocks - do nothing... */ },
@@ -1281,7 +1283,8 @@
 	}
 	
 	/* if collapsed, don't go any further (unless adding keyframes only) */
-	if ( (EXPANDED_OBJC(ob) == 0) && !(filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) )
+	if ( ((filter_mode & ANIMFILTER_VISIBLE) && EXPANDED_OBJC(ob) == 0) &&
+		 !(filter_mode & (ANIMFILTER_CURVESONLY|ANIMFILTER_NLATRACKS)) )
 		return items;
 	
 	/* Action, Drivers, or NLA */
@@ -1304,7 +1307,7 @@
 				}
 				
 				/* add F-Curve channels (drivers are F-Curves) */
-				if (EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) {
+				if (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_DRVD(adt) || !(filter_mode & ANIMFILTER_CHANNELS)) {
 					// need to make the ownertype normal object here... (maybe type should be a separate one for clarity?)
 					items += animdata_filter_fcurves(anim_data, ads, adt->drivers.first, NULL, ob, ANIMTYPE_OBJECT, filter_mode, (ID *)ob);
 				}
@@ -1320,7 +1323,7 @@
 				}
 				
 				/* add F-Curve channels? */
-				if (EXPANDED_ACTC(adt->action) || !(filter_mode & ANIMFILTER_CHANNELS)) {
+				if (!(filter_mode & ANIMFILTER_VISIBLE) || EXPANDED_ACTC(adt->action) || !(filter_mode & ANIMFILTER_CHANNELS)) {
 					// need to make the ownertype normal object here... (maybe type should be a separate one for clarity?)
 					items += animdata_filter_action(anim_data, ads, adt->action, filter_mode, ob, ANIMTYPE_OBJECT, (ID *)ob); 
 				}
@@ -1348,7 +1351,7 @@
 				}
 				
 				/* add NLA tracks - only if expanded or so */
-				if (FILTER_SKE_OBJD(key) || (filter_mode & ANIMFILTER_CURVESONLY))

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list