[Bf-blender-cvs] [89abdb6] master: DopeSheet: View Selected recenters the view vertically to display the active channel

Joshua Leung noreply at git.blender.org
Fri May 9 05:51:32 CEST 2014


Commit: 89abdb606d4e106385b313cfb8c8b2250118ca4d
Author: Joshua Leung
Date:   Fri May 9 15:07:52 2014 +1200
https://developer.blender.org/rB89abdb606d4e106385b313cfb8c8b2250118ca4d

DopeSheet: View Selected recenters the view vertically to display the active channel

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

M	source/blender/editors/space_action/action_edit.c

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

diff --git a/source/blender/editors/space_action/action_edit.c b/source/blender/editors/space_action/action_edit.c
index 9128431..f38c94a 100644
--- a/source/blender/editors/space_action/action_edit.c
+++ b/source/blender/editors/space_action/action_edit.c
@@ -362,7 +362,112 @@ void ACTION_OT_previewrange_set(wmOperatorType *ot)
 
 /* ****************** View-All Operator ****************** */
 
-static int actkeys_viewall(bContext *C, const bool only_sel, const bool only_xaxis)
+/* Find the extents of the active channel
+ * > min: (float) bottom y-extent of channel
+ * > max: (float) top y-extent of channel
+ * > returns: success of finding a selected channel
+ */
+static bool actkeys_channels_get_selected_extents(bAnimContext *ac, float *min, float *max)
+{
+	ListBase anim_data = {NULL, NULL};
+	bAnimListElem *ale;
+	int filter;
+	
+	short found = 0; /* NOTE: not bool, since we want prioritise individual channels over expanders */
+	float y;
+	
+	/* get all items - we need to do it this way */
+	filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_LIST_VISIBLE | ANIMFILTER_LIST_CHANNELS);
+	ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+	
+	/* loop through all channels, finding the first one that's selected */
+	y = (float)ACHANNEL_FIRST;
+	
+	for (ale = anim_data.first; ale; ale = ale->next) {
+		bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+		
+		/* must be selected... */
+		if (acf && acf->has_setting(ac, ale, ACHANNEL_SETTING_SELECT) && 
+		    ANIM_channel_setting_get(ac, ale, ACHANNEL_SETTING_SELECT))
+		{
+			/* update best estimate */
+			*min = (float)(y - ACHANNEL_HEIGHT_HALF);
+			*max = (float)(y + ACHANNEL_HEIGHT_HALF);
+			
+			/* is this high enough priority yet? */
+			// TODO: refactor this check out into a utility function, and share this with other places which do stuff like this
+			switch (ale->type) {
+				/* datablock expanders - ignore unless nothing else comes along */
+				case ANIMTYPE_SUMMARY:
+					found = -1;
+					break;
+					
+				case ANIMTYPE_SCENE:
+				case ANIMTYPE_OBJECT:
+					found = -1;
+					break;
+				
+				case ANIMTYPE_FILLACTD:
+				case ANIMTYPE_FILLDRIVERS:
+				case ANIMTYPE_DSMAT:
+				case ANIMTYPE_DSLAM:
+				case ANIMTYPE_DSCAM:
+				case ANIMTYPE_DSCUR:
+				case ANIMTYPE_DSSKEY:
+				case ANIMTYPE_DSWOR:
+				case ANIMTYPE_DSNTREE:
+				case ANIMTYPE_DSPART:
+				case ANIMTYPE_DSMBALL:
+				case ANIMTYPE_DSARM:
+				case ANIMTYPE_DSMESH:
+				case ANIMTYPE_DSTEX:
+				case ANIMTYPE_DSLAT:
+				case ANIMTYPE_DSLINESTYLE:
+				case ANIMTYPE_DSSPK:
+					found = -1;
+					break;
+					
+				case ANIMTYPE_GPDATABLOCK:
+				case ANIMTYPE_MASKDATABLOCK:
+					found = -1;
+					break;
+				
+				
+				/* actual channels */
+				case ANIMTYPE_GROUP:
+				case ANIMTYPE_FCURVE:
+				case ANIMTYPE_SHAPEKEY:
+					found = 1;
+					break;
+				
+				case ANIMTYPE_GPLAYER:
+				case ANIMTYPE_MASKLAYER:
+					found = 1;
+					break;
+				
+				default: /* irrelevant */
+					break;
+			}
+			
+			/* only stop our search when we've found an actual channel
+			 * - datablock expanders get less priority so that we don't abort prematurely
+			 */
+			if (found > 0) {
+				break;
+			}
+		}
+		
+		/* adjust y-position for next one */
+		y -= ACHANNEL_STEP;
+	}
+	
+	/* free all temp data */
+	BLI_freelistN(&anim_data);
+	
+	return (found != 0);
+}
+
+static int actkeys_viewall(bContext *C, const bool only_sel)
 {
 	bAnimContext ac;
 	View2D *v2d;
@@ -388,10 +493,25 @@ static int actkeys_viewall(bContext *C, const bool only_sel, const bool only_xax
 	v2d->cur.xmax += extra;
 	
 	/* set vertical range */
-	if (only_xaxis == false) {
+	if (only_sel == false) {
+		/* view all -> the summary channel is usually the shows everything, and resides right at the top... */
 		v2d->cur.ymax = 0.0f;
 		v2d->cur.ymin = (float)-BLI_rcti_size_y(&v2d->mask);
 	}
+	else {
+		/* locate first selected channel (or the active one), and frame those */
+		float ymin = v2d->cur.ymin;
+		float ymax = v2d->cur.ymax;
+		
+		if (actkeys_channels_get_selected_extents(&ac, &ymin, &ymax)) {
+			/* recenter the view so that this range is in the middle */
+			float ymid = (ymax - ymin) / 2.0f + ymin;
+			float x_center;
+			
+			UI_view2d_center_get(v2d, &x_center, NULL);
+			UI_view2d_center_set(v2d, x_center, ymid);
+		}
+	}
 	
 	/* do View2D syncing */
 	UI_view2d_sync(CTX_wm_screen(C), CTX_wm_area(C), v2d, V2D_LOCK_COPY);
@@ -407,13 +527,13 @@ static int actkeys_viewall(bContext *C, const bool only_sel, const bool only_xax
 static int actkeys_viewall_exec(bContext *C, wmOperator *UNUSED(op))
 {	
 	/* whole range */
-	return actkeys_viewall(C, false, false);
+	return actkeys_viewall(C, false);
 }
 
 static int actkeys_viewsel_exec(bContext *C, wmOperator *UNUSED(op))
 {
 	/* only selected */
-	return actkeys_viewall(C, true, true);
+	return actkeys_viewall(C, true);
 }
  
 void ACTION_OT_view_all(wmOperatorType *ot)




More information about the Bf-blender-cvs mailing list