Exemplo n.º 1
0
/* drivers panel poll */
static int graph_panel_drivers_poll(const bContext *C, PanelType *UNUSED(pt))
{
	SpaceIpo *sipo = CTX_wm_space_graph(C);

	if (sipo->mode != SIPO_MODE_DRIVERS)
		return 0;

	return graph_panel_context(C, NULL, NULL);
}
Exemplo n.º 2
0
static void graph_panel_key_properties(const bContext *C, Panel *pa)
{
	bAnimListElem *ale;
	FCurve *fcu;
	BezTriple *bezt, *prevbezt;
	
	uiLayout *layout = pa->layout;
	uiLayout *col;
	uiBlock *block;

	if (!graph_panel_context(C, &ale, &fcu))
		return;
	
	block = uiLayoutGetBlock(layout);
	uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL);
	
	/* only show this info if there are keyframes to edit */
	if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) {
		PointerRNA bezt_ptr;
		
		/* RNA pointer to keyframe, to allow editing */
		RNA_pointer_create(ale->id, &RNA_Keyframe, bezt, &bezt_ptr);
		
		/* interpolation */
		col= uiLayoutColumn(layout, 0);
			uiItemR(col, &bezt_ptr, "interpolation", 0, NULL, ICON_NONE);
			
		/* numerical coordinate editing */
		col= uiLayoutColumn(layout, 1);
			/* keyframe itself */
			uiItemR(col, &bezt_ptr, "co", 0, "Key", ICON_NONE);
			
			/* previous handle - only if previous was Bezier interpolation */
			if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ))
				uiItemR(col, &bezt_ptr, "handle_left", 0, NULL, ICON_NONE);
			
			/* next handle - only if current is Bezier interpolation */
			if (bezt->ipo == BEZT_IPO_BEZ)
				uiItemR(col, &bezt_ptr, "handle_right", 0, NULL, ICON_NONE);
	}
	else {
		if ((fcu->bezt == NULL) && (fcu->modifiers.first)) {
			/* modifiers only - so no keyframes to be active */
			uiItemL(layout, "F-Curve only has F-Modifiers", ICON_NONE);
			uiItemL(layout, "See Modifiers panel below", ICON_INFO);
		}
		else if (fcu->fpt) {
			/* samples only */
			uiItemL(layout, "F-Curve doesn't have any keyframes as it only contains sampled points", ICON_NONE);
		}
		else
			uiItemL(layout, "No active keyframe on F-Curve", ICON_NONE);
	}
	
	MEM_freeN(ale);
}
Exemplo n.º 3
0
static void graph_panel_properties(const bContext *C, Panel *pa)
{
	bAnimListElem *ale;
	FCurve *fcu;
	PointerRNA fcu_ptr;
	uiLayout *layout = pa->layout;
	uiLayout *col, *row, *sub;
	// uiBlock *block;  // UNUSED
	char name[256];
	int icon = 0;

	if (!graph_panel_context(C, &ale, &fcu))
		return;
	
	// UNUSED
	// block = uiLayoutGetBlock(layout);
	// uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL);
	
	/* F-Curve pointer */
	RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr);
	
	/* user-friendly 'name' for F-Curve */
	/* TODO: only show the path if this is invalid? */
	col = uiLayoutColumn(layout, false);
	icon = getname_anim_fcurve(name, ale->id, fcu);
	uiItemL(col, name, icon);
		
	/* RNA-Path Editing - only really should be enabled when things aren't working */
	col = uiLayoutColumn(layout, true);
	uiLayoutSetEnabled(col, (fcu->flag & FCURVE_DISABLED) != 0);
	uiItemR(col, &fcu_ptr, "data_path", 0, "", ICON_RNA);
	uiItemR(col, &fcu_ptr, "array_index", 0, NULL, ICON_NONE);
		
	/* color settings */
	col = uiLayoutColumn(layout, true);
	uiItemL(col, IFACE_("Display Color:"), ICON_NONE);
		
	row = uiLayoutRow(col, true);
	uiItemR(row, &fcu_ptr, "color_mode", 0, "", ICON_NONE);
			
	sub = uiLayoutRow(row, true);
	uiLayoutSetEnabled(sub, (fcu->color_mode == FCURVE_COLOR_CUSTOM));
	uiItemR(sub, &fcu_ptr, "color", 0, "", ICON_NONE);
	
	MEM_freeN(ale);
}
Exemplo n.º 4
0
static void graph_panel_modifiers(const bContext *C, Panel *pa)	
{
	bAnimListElem *ale;
	FCurve *fcu;
	FModifier *fcm;
	uiLayout *col, *row;
	uiBlock *block;
	bool active;
	
	if (!graph_panel_context(C, &ale, &fcu))
		return;
	
	block = uiLayoutGetBlock(pa->layout);
	UI_block_func_handle_set(block, do_graph_region_modifier_buttons, NULL);
	
	/* 'add modifier' button at top of panel */
	{
		row = uiLayoutRow(pa->layout, false);
		
		/* this is an operator button which calls a 'add modifier' operator... 
		 * a menu might be nicer but would be tricky as we need some custom filtering
		 */
		uiItemMenuEnumO(row, (bContext *)C, "GRAPH_OT_fmodifier_add", "type", IFACE_("Add Modifier"), ICON_NONE);
		
		/* copy/paste (as sub-row) */
		row = uiLayoutRow(row, true);
		uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_fmodifier_copy");
		uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_fmodifier_paste");
	}
	
	active = !(fcu->flag & FCURVE_MOD_OFF);
	/* draw each modifier */
	for (fcm = fcu->modifiers.first; fcm; fcm = fcm->next) {
		col = uiLayoutColumn(pa->layout, true);
		uiLayoutSetActive(col, active);
		
		ANIM_uiTemplate_fmodifier_draw(col, ale->id, &fcu->modifiers, fcm);
	}
	
	MEM_freeN(ale);
}
Exemplo n.º 5
0
static void graph_panel_modifiers(const bContext *C, Panel *pa)	
{
	bAnimListElem *ale;
	FCurve *fcu;
	FModifier *fcm;
	uiLayout *col, *row;
	uiBlock *block;
	
	if (!graph_panel_context(C, &ale, &fcu))
		return;
	
	block = uiLayoutGetBlock(pa->layout);
	uiBlockSetHandleFunc(block, do_graph_region_modifier_buttons, NULL);
	
	/* 'add modifier' button at top of panel */
	{
		row = uiLayoutRow(pa->layout, false);
		block = uiLayoutGetBlock(row);
		
		/* this is an operator button which calls a 'add modifier' operator... 
		 * a menu might be nicer but would be tricky as we need some custom filtering
		 */
		uiDefButO(block, BUT, "GRAPH_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"),
		          0.5 * UI_UNIT_X, 0, 7.5 * UI_UNIT_X, UI_UNIT_Y, TIP_("Adds a new F-Curve Modifier for the active F-Curve"));
		
		/* copy/paste (as sub-row)*/
		row = uiLayoutRow(row, true);
		uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_fmodifier_copy");
		uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_fmodifier_paste");
	}
	
	/* draw each modifier */
	for (fcm = fcu->modifiers.first; fcm; fcm = fcm->next) {
		col = uiLayoutColumn(pa->layout, true);
		
		ANIM_uiTemplate_fmodifier_draw(col, ale->id, &fcu->modifiers, fcm);
	}

	MEM_freeN(ale);
}
Exemplo n.º 6
0
static void graph_panel_modifiers(const bContext *C, Panel *pa)	
{
	bAnimListElem *ale;
	FCurve *fcu;
	FModifier *fcm;
	uiLayout *col, *row;
	uiBlock *block;
	
	if (!graph_panel_context(C, &ale, &fcu))
		return;
	
	block = uiLayoutGetBlock(pa->layout);
	uiBlockSetHandleFunc(block, do_graph_region_modifier_buttons, NULL);
	
	/* 'add modifier' button at top of panel */
	{
		row = uiLayoutRow(pa->layout, FALSE);
		block = uiLayoutGetBlock(row);
		
		// XXX for now, this will be a operator button which calls a 'add modifier' operator
		uiDefButO(block, BUT, "GRAPH_OT_fmodifier_add", WM_OP_INVOKE_REGION_WIN, IFACE_("Add Modifier"),
		          10, 0, 150, 20, TIP_("Adds a new F-Curve Modifier for the active F-Curve"));
		
		/* copy/paste (as sub-row)*/
		row = uiLayoutRow(row, TRUE);
		uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_fmodifier_copy");
		uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_fmodifier_paste");
	}
	
	/* draw each modifier */
	for (fcm = fcu->modifiers.first; fcm; fcm = fcm->next) {
		col = uiLayoutColumn(pa->layout, TRUE);
		
		ANIM_uiTemplate_fmodifier_draw(col, ale->id, &fcu->modifiers, fcm);
	}

	MEM_freeN(ale);
}
Exemplo n.º 7
0
/* driver settings for active F-Curve (only for 'Drivers' mode) */
static void graph_panel_drivers(const bContext *C, Panel *pa)
{
	bAnimListElem *ale;
	FCurve *fcu;
	ChannelDriver *driver;
	DriverVar *dvar;
	
	PointerRNA driver_ptr;
	uiLayout *col;
	uiBlock *block;
	uiBut *but;
	
	/* Get settings from context */
	if (!graph_panel_context(C, &ale, &fcu))
		return;
	driver = fcu->driver;
	
	/* set event handler for panel */
	block = uiLayoutGetBlock(pa->layout); // xxx?
	uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL);
	
	/* general actions - management */
	col = uiLayoutColumn(pa->layout, FALSE);
	block = uiLayoutGetBlock(col);
	but = uiDefBut(block, BUT, B_IPO_DEPCHANGE, IFACE_("Update Dependencies"), 0, 0, 10 * UI_UNIT_X, 22,
	               NULL, 0.0, 0.0, 0, 0, TIP_("Force updates of dependencies"));
	uiButSetFunc(but, driver_update_flags_cb, fcu, NULL);

	but = uiDefBut(block, BUT, B_IPO_DEPCHANGE, IFACE_("Remove Driver"), 0, 0, 10 * UI_UNIT_X, 18,
	               NULL, 0.0, 0.0, 0, 0, TIP_("Remove this driver"));
	uiButSetNFunc(but, driver_remove_cb, MEM_dupallocN(ale), NULL);
		
	/* driver-level settings - type, expressions, and errors */
	RNA_pointer_create(ale->id, &RNA_Driver, driver, &driver_ptr);
	
	col = uiLayoutColumn(pa->layout, TRUE);
	block = uiLayoutGetBlock(col);
	uiItemR(col, &driver_ptr, "type", 0, NULL, ICON_NONE);

	/* show expression box if doing scripted drivers, and/or error messages when invalid drivers exist */
	if (driver->type == DRIVER_TYPE_PYTHON) {
		/* expression */
		uiItemR(col, &driver_ptr, "expression", 0, IFACE_("Expr"), ICON_NONE);

		/* errors? */
		if (driver->flag & DRIVER_FLAG_INVALID)
			uiItemL(col, IFACE_("ERROR: invalid Python expression"), ICON_ERROR);
	}
	else {
		/* errors? */
		if (driver->flag & DRIVER_FLAG_INVALID)
			uiItemL(col, IFACE_("ERROR: invalid target channel(s)"), ICON_ERROR);
	}
		
	col = uiLayoutColumn(pa->layout, TRUE);
	/* debug setting */
	uiItemR(col, &driver_ptr, "show_debug_info", 0, NULL, ICON_NONE);
		
	/* value of driver */
	if (driver->flag & DRIVER_FLAG_SHOWDEBUG) {
		uiLayout *row = uiLayoutRow(col, TRUE);
		char valBuf[32];
			
		uiItemL(row, IFACE_("Driver Value:"), ICON_NONE);
			
		BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", driver->curval);
		uiItemL(row, valBuf, ICON_NONE);
	}
	
	/* add driver variables */
	col = uiLayoutColumn(pa->layout, FALSE);
	block = uiLayoutGetBlock(col);
	but = uiDefBut(block, BUT, B_IPO_DEPCHANGE, IFACE_("Add Variable"), 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
	               NULL, 0.0, 0.0, 0, 0, TIP_("Add a new target variable for this Driver"));
	uiButSetFunc(but, driver_add_var_cb, driver, NULL);
	
	/* loop over targets, drawing them */
	for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
		PointerRNA dvar_ptr;
		uiLayout *box, *row;
		
		/* sub-layout column for this variable's settings */
		col = uiLayoutColumn(pa->layout, TRUE);
		
		/* header panel */
		box = uiLayoutBox(col);
		/* first row context info for driver */
		RNA_pointer_create(ale->id, &RNA_DriverVariable, dvar, &dvar_ptr);

		row = uiLayoutRow(box, FALSE);
		block = uiLayoutGetBlock(row);
		/* variable name */
		uiItemR(row, &dvar_ptr, "name", 0, "", ICON_NONE);

		/* remove button */
		uiBlockSetEmboss(block, UI_EMBOSSN);
		but = uiDefIconBut(block, BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y,
		                   NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Delete target variable"));
		uiButSetFunc(but, driver_delete_var_cb, driver, dvar);
		uiBlockSetEmboss(block, UI_EMBOSS);

		/* variable type */
		row = uiLayoutRow(box, FALSE);
		uiItemR(row, &dvar_ptr, "type", 0, "", ICON_NONE);
				
		/* variable type settings */
		box = uiLayoutBox(col);
		/* controls to draw depends on the type of variable */
		switch (dvar->type) {
			case DVAR_TYPE_SINGLE_PROP:     /* single property */
				graph_panel_driverVar__singleProp(box, ale->id, dvar);
				break;
			case DVAR_TYPE_ROT_DIFF:     /* rotational difference */
				graph_panel_driverVar__rotDiff(box, ale->id, dvar);
				break;
			case DVAR_TYPE_LOC_DIFF:     /* location difference */
				graph_panel_driverVar__locDiff(box, ale->id, dvar);
				break;
			case DVAR_TYPE_TRANSFORM_CHAN:     /* transform channel */
				graph_panel_driverVar__transChan(box, ale->id, dvar);
				break;
		}

		/* value of variable */
		if (driver->flag & DRIVER_FLAG_SHOWDEBUG) {
			char valBuf[32];

			box = uiLayoutBox(col);
			row = uiLayoutRow(box, TRUE);
			uiItemL(row, IFACE_("Value:"), ICON_NONE);

			BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval);
			uiItemL(row, valBuf, ICON_NONE);
		}
	}
	
	/* cleanup */
	MEM_freeN(ale);
}
Exemplo n.º 8
0
static void graph_panel_key_properties(const bContext *C, Panel *pa)
{
	bAnimListElem *ale;
	FCurve *fcu;
	BezTriple *bezt, *prevbezt;
	
	uiLayout *layout = pa->layout;
	uiLayout *col;
	uiBlock *block;

	if (!graph_panel_context(C, &ale, &fcu))
		return;
	
	block = uiLayoutGetBlock(layout);
	uiBlockSetHandleFunc(block, do_graph_region_buttons, NULL);
	
	/* only show this info if there are keyframes to edit */
	if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) {
		PointerRNA bezt_ptr, id_ptr, fcu_prop_ptr;
		PropertyRNA *fcu_prop = NULL;
		uiBut *but;
		int unit = B_UNIT_NONE;
		
		/* RNA pointer to keyframe, to allow editing */
		RNA_pointer_create(ale->id, &RNA_Keyframe, bezt, &bezt_ptr);
		
		/* get property that F-Curve affects, for some unit-conversion magic */
		RNA_id_pointer_create(ale->id, &id_ptr);
		if (RNA_path_resolve(&id_ptr, fcu->rna_path, &fcu_prop_ptr, &fcu_prop) && fcu_prop) {
			/* determine the unit for this property */
			unit = RNA_SUBTYPE_UNIT(RNA_property_subtype(fcu_prop));
		}		
		
		/* interpolation */
		col = uiLayoutColumn(layout, FALSE);
		uiItemR(col, &bezt_ptr, "interpolation", 0, NULL, ICON_NONE);
			
		/* numerical coordinate editing 
		 *  - we use the button-versions of the calls so that we can attach special update handlers
		 *    and unit conversion magic that cannot be achieved using a purely RNA-approach
		 */
		// XXX: 
		col = uiLayoutColumn(layout, TRUE);
		/* keyframe itself */
		{
			uiItemL(col, IFACE_("Key:"), ICON_NONE);

			but = uiDefButR(block, NUM, B_REDR, IFACE_("Frame"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "co", 0, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt);

			but = uiDefButR(block, NUM, B_REDR, IFACE_("Value"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "co", 1, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_update_cb, fcu, bezt);
			uiButSetUnitType(but, unit);
		}

		/* previous handle - only if previous was Bezier interpolation */
		if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
			uiItemL(col, IFACE_("Left Handle:"), ICON_NONE);

			but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);

			but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
			uiButSetUnitType(but, unit);
		}

		/* next handle - only if current is Bezier interpolation */
		if (bezt->ipo == BEZT_IPO_BEZ) {
			uiItemL(col, IFACE_("Right Handle:"), ICON_NONE);

			but = uiDefButR(block, NUM, B_REDR, "X", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);

			but = uiDefButR(block, NUM, B_REDR, "Y", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL);
			uiButSetFunc(but, graphedit_activekey_handles_cb, fcu, bezt);
			uiButSetUnitType(but, unit);
		}
	}
	else {
		if ((fcu->bezt == NULL) && (fcu->modifiers.first)) {
			/* modifiers only - so no keyframes to be active */
			uiItemL(layout, IFACE_("F-Curve only has F-Modifiers"), ICON_NONE);
			uiItemL(layout, IFACE_("See Modifiers panel below"), ICON_INFO);
		}
		else if (fcu->fpt) {
			/* samples only */
			uiItemL(layout, IFACE_("F-Curve doesn't have any keyframes as it only contains sampled points"),
			        ICON_NONE);
		}
		else
			uiItemL(layout, IFACE_("No active keyframe on F-Curve"), ICON_NONE);
	}
	
	MEM_freeN(ale);
}
Exemplo n.º 9
0
static int graph_panel_poll(const bContext *C, PanelType *UNUSED(pt))
{
	return graph_panel_context(C, NULL, NULL);
}
Exemplo n.º 10
0
/* driver settings for active F-Curve (only for 'Drivers' mode) */
static void graph_panel_drivers(const bContext *C, Panel *pa)
{
	bAnimListElem *ale;
	FCurve *fcu;
	ChannelDriver *driver;
	DriverVar *dvar;
	
	PointerRNA driver_ptr;
	uiLayout *col;
	uiBlock *block;
	uiBut *but;
	
	/* Get settings from context */
	if (!graph_panel_context(C, &ale, &fcu))
		return;
	driver = fcu->driver;
	
	/* set event handler for panel */
	block = uiLayoutGetBlock(pa->layout); // xxx?
	uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL);
	
	/* general actions - management */
	col = uiLayoutColumn(pa->layout, false);
	block = uiLayoutGetBlock(col);
	but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"),
	               0, 0, 10 * UI_UNIT_X, 22,
	               NULL, 0.0, 0.0, 0, 0,
	               TIP_("Force updates of dependencies"));
	uiButSetFunc(but, driver_update_flags_cb, fcu, NULL);

	but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_ZOOMOUT, IFACE_("Remove Driver"),
	               0, 0, 10 * UI_UNIT_X, 18,
	               NULL, 0.0, 0.0, 0, 0,
	               TIP_("Remove this driver"));
	uiButSetNFunc(but, driver_remove_cb, MEM_dupallocN(ale), NULL);
		
	/* driver-level settings - type, expressions, and errors */
	RNA_pointer_create(ale->id, &RNA_Driver, driver, &driver_ptr);
	
	col = uiLayoutColumn(pa->layout, true);
	block = uiLayoutGetBlock(col);
	uiItemR(col, &driver_ptr, "type", 0, NULL, ICON_NONE);

	/* show expression box if doing scripted drivers, and/or error messages when invalid drivers exist */
	if (driver->type == DRIVER_TYPE_PYTHON) {
		bool bpy_data_expr_error = (strstr(driver->expression, "bpy.data.") != NULL);
		bool bpy_ctx_expr_error  = (strstr(driver->expression, "bpy.context.") != NULL);
		
		/* expression */
		uiItemR(col, &driver_ptr, "expression", 0, IFACE_("Expr"), ICON_NONE);
		
		/* errors? */
		if ((G.f & G_SCRIPT_AUTOEXEC) == 0) {
			uiItemL(col, IFACE_("ERROR: Python auto-execution disabled"), ICON_CANCEL);
		}
		else if (driver->flag & DRIVER_FLAG_INVALID) {
			uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_CANCEL);
		}
		
		/* Explicit bpy-references are evil. Warn about these to prevent errors */
		/* TODO: put these in a box? */
		if (bpy_data_expr_error || bpy_ctx_expr_error) {
			uiItemL(col, IFACE_("WARNING: Driver expression may not work correctly"), ICON_HELP);
			
			if (bpy_data_expr_error) {
				uiItemL(col, IFACE_("TIP: Use variables instead of bpy.data paths (see below)"), ICON_ERROR);
			}
			if (bpy_ctx_expr_error) {
				uiItemL(col, IFACE_("TIP: bpy.context is not safe for renderfarm usage"), ICON_ERROR);
			}
		}
	}
	else {
		/* errors? */
		if (driver->flag & DRIVER_FLAG_INVALID)
			uiItemL(col, IFACE_("ERROR: Invalid target channel(s)"), ICON_ERROR);
			
		/* Warnings about a lack of variables
		 * NOTE: The lack of variables is generally a bad thing, since it indicates
		 *       that the driver doesn't work at all. This particular scenario arises
		 *       primarily when users mistakenly try to use drivers for procedural
		 *       property animation
		 */
		if (BLI_listbase_is_empty(&driver->variables)) {
			uiItemL(col, IFACE_("ERROR: Driver is useless without any inputs"), ICON_ERROR);
			
			if (!BLI_listbase_is_empty(&fcu->modifiers)) {
				uiItemL(col, IFACE_("TIP: Use F-Curves for procedural animation instead"), ICON_INFO);
				uiItemL(col, IFACE_("F-Modifiers can generate curves for those too"), ICON_INFO);
			}
		}
	}
		
	col = uiLayoutColumn(pa->layout, true);
	/* debug setting */
	uiItemR(col, &driver_ptr, "show_debug_info", 0, NULL, ICON_NONE);
		
	/* value of driver */
	if (driver->flag & DRIVER_FLAG_SHOWDEBUG) {
		uiLayout *row = uiLayoutRow(col, true);
		char valBuf[32];
			
		uiItemL(row, IFACE_("Driver Value:"), ICON_NONE);
			
		BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", driver->curval);
		uiItemL(row, valBuf, ICON_NONE);
	}
	
	/* add driver variables */
	col = uiLayoutColumn(pa->layout, false);
	block = uiLayoutGetBlock(col);
	but = uiDefIconTextBut(block, BUT, B_IPO_DEPCHANGE, ICON_ZOOMIN, IFACE_("Add Variable"),
	               0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
	               NULL, 0.0, 0.0, 0, 0,
	               TIP_("Driver variables ensure that all dependencies will be accounted for and that drivers will update correctly"));
	uiButSetFunc(but, driver_add_var_cb, driver, NULL);
	
	/* loop over targets, drawing them */
	for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
		PointerRNA dvar_ptr;
		uiLayout *box, *row;
		
		/* sub-layout column for this variable's settings */
		col = uiLayoutColumn(pa->layout, true);
		
		/* header panel */
		box = uiLayoutBox(col);
		/* first row context info for driver */
		RNA_pointer_create(ale->id, &RNA_DriverVariable, dvar, &dvar_ptr);
		
		row = uiLayoutRow(box, false);
		block = uiLayoutGetBlock(row);
		/* variable name */
		uiItemR(row, &dvar_ptr, "name", 0, "", ICON_NONE);
		
		/* remove button */
		uiBlockSetEmboss(block, UI_EMBOSSN);
		but = uiDefIconBut(block, BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y,
		                   NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Delete target variable"));
		uiButSetFunc(but, driver_delete_var_cb, driver, dvar);
		uiBlockSetEmboss(block, UI_EMBOSS);
		
		/* variable type */
		row = uiLayoutRow(box, false);
		uiItemR(row, &dvar_ptr, "type", 0, "", ICON_NONE);
				
		/* variable type settings */
		box = uiLayoutBox(col);
		/* controls to draw depends on the type of variable */
		switch (dvar->type) {
			case DVAR_TYPE_SINGLE_PROP:     /* single property */
				graph_panel_driverVar__singleProp(box, ale->id, dvar);
				break;
			case DVAR_TYPE_ROT_DIFF:     /* rotational difference */
				graph_panel_driverVar__rotDiff(box, ale->id, dvar);
				break;
			case DVAR_TYPE_LOC_DIFF:     /* location difference */
				graph_panel_driverVar__locDiff(box, ale->id, dvar);
				break;
			case DVAR_TYPE_TRANSFORM_CHAN:     /* transform channel */
				graph_panel_driverVar__transChan(box, ale->id, dvar);
				break;
		}
		
		/* value of variable */
		if (driver->flag & DRIVER_FLAG_SHOWDEBUG) {
			char valBuf[32];
			
			box = uiLayoutBox(col);
			row = uiLayoutRow(box, true);
			uiItemL(row, IFACE_("Value:"), ICON_NONE);
			
			if ((dvar->type == DVAR_TYPE_ROT_DIFF) ||
			    (dvar->type == DVAR_TYPE_TRANSFORM_CHAN &&
			     dvar->targets[0].transChan >= DTAR_TRANSCHAN_ROTX &&
			     dvar->targets[0].transChan < DTAR_TRANSCHAN_SCALEX))
			{
				BLI_snprintf(valBuf, sizeof(valBuf), "%.3f (%4.1f°)", dvar->curval, RAD2DEGF(dvar->curval));
			}
			else {
				BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval);
			}
			
			uiItemL(row, valBuf, ICON_NONE);
		}
	}
	
	/* cleanup */
	MEM_freeN(ale);
}
Exemplo n.º 11
0
static void graph_panel_key_properties(const bContext *C, Panel *pa)
{
	bAnimListElem *ale;
	FCurve *fcu;
	BezTriple *bezt, *prevbezt;
	
	uiLayout *layout = pa->layout;
	uiLayout *col;
	uiBlock *block;

	if (!graph_panel_context(C, &ale, &fcu))
		return;
	
	block = uiLayoutGetBlock(layout);
	/* UI_block_func_handle_set(block, do_graph_region_buttons, NULL); */
	
	/* only show this info if there are keyframes to edit */
	if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) {
		PointerRNA bezt_ptr, id_ptr, fcu_prop_ptr;
		PropertyRNA *fcu_prop = NULL;
		uiBut *but;
		int unit = B_UNIT_NONE;
		
		/* RNA pointer to keyframe, to allow editing */
		RNA_pointer_create(ale->id, &RNA_Keyframe, bezt, &bezt_ptr);
		
		/* get property that F-Curve affects, for some unit-conversion magic */
		RNA_id_pointer_create(ale->id, &id_ptr);
		if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &fcu_prop_ptr, &fcu_prop)) {
			/* determine the unit for this property */
			unit = RNA_SUBTYPE_UNIT(RNA_property_subtype(fcu_prop));
		}
		
		/* interpolation */
		col = uiLayoutColumn(layout, false);
		if (fcu->flag & FCURVE_DISCRETE_VALUES) {
			uiLayout *split = uiLayoutSplit(col, 0.33f, true);
			uiItemL(split, IFACE_("Interpolation:"), ICON_NONE);
			uiItemL(split, IFACE_("None for Enum/Boolean"), ICON_IPO_CONSTANT);
		}
		else {
			uiItemR(col, &bezt_ptr, "interpolation", 0, NULL, ICON_NONE);
		}
		
		/* easing type */
		if (bezt->ipo > BEZT_IPO_BEZ)
			uiItemR(col, &bezt_ptr, "easing", 0, NULL, 0);

		/* easing extra */
		switch (bezt->ipo) {
			case BEZT_IPO_BACK:
				col = uiLayoutColumn(layout, 1);
				uiItemR(col, &bezt_ptr, "back", 0, NULL, 0);
				break;
			case BEZT_IPO_ELASTIC:
				col = uiLayoutColumn(layout, 1);
				uiItemR(col, &bezt_ptr, "amplitude", 0, NULL, 0);
				uiItemR(col, &bezt_ptr, "period", 0, NULL, 0);
				break;
			default:
				break;
		}
		
		/* numerical coordinate editing 
		 *  - we use the button-versions of the calls so that we can attach special update handlers
		 *    and unit conversion magic that cannot be achieved using a purely RNA-approach
		 */
		col = uiLayoutColumn(layout, true);
		/* keyframe itself */
		{
			uiItemL(col, IFACE_("Key:"), ICON_NONE);
			
			but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Frame:"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "co", 0, 0, 0, -1, -1, NULL);
			UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
			
			but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Value:"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "co", 1, 0, 0, -1, -1, NULL);
			UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
			UI_but_unit_type_set(but, unit);
		}
		
		/* previous handle - only if previous was Bezier interpolation */
		if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
			uiItemL(col, IFACE_("Left Handle:"), ICON_NONE);
			
			but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL);
			UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
			
			but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL);
			UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
			UI_but_unit_type_set(but, unit);
			
			/* XXX: with label? */
			but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_left_type", 0, 0, 0, -1, -1, "Type of left handle");
			UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
		}
		
		/* next handle - only if current is Bezier interpolation */
		if (bezt->ipo == BEZT_IPO_BEZ) {
			/* NOTE: special update callbacks are needed on the coords here due to T39911 */
			uiItemL(col, IFACE_("Right Handle:"), ICON_NONE);
			
			but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL);
			UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
			
			but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL);
			UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
			UI_but_unit_type_set(but, unit);
			
			/* XXX: with label? */
			but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
			                &bezt_ptr, "handle_right_type", 0, 0, 0, -1, -1, "Type of right handle");
			UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
		}
	}
	else {
		if ((fcu->bezt == NULL) && (fcu->modifiers.first)) {
			/* modifiers only - so no keyframes to be active */
			uiItemL(layout, IFACE_("F-Curve only has F-Modifiers"), ICON_NONE);
			uiItemL(layout, IFACE_("See Modifiers panel below"), ICON_INFO);
		}
		else if (fcu->fpt) {
			/* samples only */
			uiItemL(layout, IFACE_("F-Curve doesn't have any keyframes as it only contains sampled points"),
			        ICON_NONE);
		}
		else
			uiItemL(layout, IFACE_("No active keyframe on F-Curve"), ICON_NONE);
	}
	
	MEM_freeN(ale);
}
Exemplo n.º 12
0
static void graph_panel_properties(const bContext *C, Panel *pa)
{
	bAnimListElem *ale;
	FCurve *fcu;
	PointerRNA fcu_ptr;
	uiLayout *layout = pa->layout;
	uiLayout *col, *row, *sub;
	// uiBlock *block;  // UNUSED
	char name[256];
	int icon = 0;

	if (!graph_panel_context(C, &ale, &fcu))
		return;
	
	// UNUSED
	// block = uiLayoutGetBlock(layout);
	// UI_block_func_handle_set(block, do_graph_region_buttons, NULL);
	
	/* F-Curve pointer */
	RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr);
	
	/* user-friendly 'name' for F-Curve */
	col = uiLayoutColumn(layout, false);
	if (ale->type == ANIMTYPE_FCURVE) {
		/* get user-friendly name for F-Curve */
		icon = getname_anim_fcurve(name, ale->id, fcu);
	}
	else {
		/* NLA Control Curve, etc. */
		const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
		
		/* get name */
		if (acf && acf->name) {
			acf->name(ale, name);
		}
		else {
			strcpy(name, IFACE_("<invalid>"));
			icon = ICON_ERROR;
		}
		
		/* icon */
		if (ale->type == ANIMTYPE_NLACURVE)
			icon = ICON_NLA;
	}
	uiItemL(col, name, icon);
		
	/* RNA-Path Editing - only really should be enabled when things aren't working */
	col = uiLayoutColumn(layout, true);
	uiLayoutSetEnabled(col, (fcu->flag & FCURVE_DISABLED) != 0);
	uiItemR(col, &fcu_ptr, "data_path", 0, "", ICON_RNA);
	uiItemR(col, &fcu_ptr, "array_index", 0, NULL, ICON_NONE);
		
	/* color settings */
	col = uiLayoutColumn(layout, true);
	uiItemL(col, IFACE_("Display Color:"), ICON_NONE);
		
	row = uiLayoutRow(col, true);
	uiItemR(row, &fcu_ptr, "color_mode", 0, "", ICON_NONE);
			
	sub = uiLayoutRow(row, true);
	uiLayoutSetEnabled(sub, (fcu->color_mode == FCURVE_COLOR_CUSTOM));
	uiItemR(sub, &fcu_ptr, "color", 0, "", ICON_NONE);
	
	MEM_freeN(ale);
}