Exemplo n.º 1
0
/* Recursively iterate over tree, finding and working on selected items */
static void do_outliner_keyingset_editop(SpaceOops *soops, KeyingSet *ks, ListBase *tree, short mode)
{
	TreeElement *te;
	TreeStoreElem *tselem;
	
	for (te= tree->first; te; te=te->next) {
		tselem= TREESTORE(te);
		
		/* if item is selected, perform operation */
		if (tselem->flag & TSE_SELECTED) {
			ID *id= NULL;
			char *path= NULL;
			int array_index= 0;
			short flag= 0;
			short groupmode= KSP_GROUP_KSNAME;
			
			/* check if RNA-property described by this selected element is an animateable prop */
			if (ELEM(tselem->type, TSE_RNA_PROPERTY, TSE_RNA_ARRAY_ELEM) && RNA_property_animateable(&te->rnaptr, te->directdata)) {
				/* get id + path + index info from the selected element */
				tree_element_to_path(soops, te, tselem, 
						&id, &path, &array_index, &flag, &groupmode);
			}
			
			/* only if ID and path were set, should we perform any actions */
			if (id && path) {
				/* action depends on mode */
				switch (mode) {
					case KEYINGSET_EDITMODE_ADD:
					{
						/* add a new path with the information obtained (only if valid) */
						// TODO: what do we do with group name? for now, we don't supply one, and just let this use the KeyingSet name
						BKE_keyingset_add_path(ks, id, NULL, path, array_index, flag, groupmode);
						ks->active_path= BLI_countlist(&ks->paths);
					}
						break;
					case KEYINGSET_EDITMODE_REMOVE:
					{
						/* find the relevant path, then remove it from the KeyingSet */
						KS_Path *ksp= BKE_keyingset_find_path(ks, id, NULL, path, array_index, groupmode);
						
						if (ksp) {
							/* free path's data */
							BKE_keyingset_free_path(ks, ksp);

							ks->active_path= 0;
						}
					}
						break;
				}
				
				/* free path, since it had to be generated */
				MEM_freeN(path);
			}
		}
		
		/* go over sub-tree */
		if ((tselem->flag & TSE_CLOSED)==0)
			do_outliner_keyingset_editop(soops, ks, &te->subtree, mode);
	}
}
Exemplo n.º 2
0
static KS_Path *rna_KeyingSet_paths_add(KeyingSet *keyingset, ReportList *reports,
                                        ID *id, const char rna_path[], int index, int group_method, const char group_name[])
{
	KS_Path *ksp = NULL;
	short flag = 0;
	
	/* special case when index = -1, we key the whole array (as with other places where index is used) */
	if (index == -1) {
		flag |= KSP_FLAG_WHOLE_ARRAY;
		index = 0;
	}
	
	/* if data is valid, call the API function for this */
	if (keyingset) {
		ksp = BKE_keyingset_add_path(keyingset, id, group_name, rna_path, index, flag, group_method);
		keyingset->active_path = BLI_countlist(&keyingset->paths);
	}
	else {
		BKE_report(reports, RPT_ERROR, "Keying set path could not be added");
	}
	
	/* return added path */
	return ksp;
}
Exemplo n.º 3
0
static int add_keyingset_button_exec(bContext *C, wmOperator *op)
{
	Scene *scene = CTX_data_scene(C);
	KeyingSet *ks = NULL;
	PropertyRNA *prop = NULL;
	PointerRNA ptr = {{NULL}};
	char *path = NULL;
	short success = 0;
	int index = 0, pflag = 0;
	const bool all = RNA_boolean_get(op->ptr, "all");
	
	/* verify the Keying Set to use:
	 *	- use the active one for now (more control over this can be added later)
	 *	- add a new one if it doesn't exist 
	 */
	if (scene->active_keyingset == 0) {
		short flag = 0, keyingflag = 0;
		
		/* validate flags 
		 *	- absolute KeyingSets should be created by default
		 */
		flag |= KEYINGSET_ABSOLUTE;
		
		keyingflag |= ANIM_get_keyframing_flags(scene, 0);
		
		if (IS_AUTOKEY_FLAG(scene, XYZ2RGB)) 
			keyingflag |= INSERTKEY_XYZ2RGB;
			
		/* call the API func, and set the active keyingset index */
		ks = BKE_keyingset_add(&scene->keyingsets, "ButtonKeyingSet", "Button Keying Set", flag, keyingflag);
		
		scene->active_keyingset = BLI_countlist(&scene->keyingsets);
	}
	else if (scene->active_keyingset < 0) {
		BKE_report(op->reports, RPT_ERROR, "Cannot add property to built in keying set");
		return OPERATOR_CANCELLED;
	}
	else {
		ks = BLI_findlink(&scene->keyingsets, scene->active_keyingset - 1);
	}
	
	/* try to add to keyingset using property retrieved from UI */
	uiContextActiveProperty(C, &ptr, &prop, &index);
	
	/* check if property is able to be added */
	if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
		path = RNA_path_from_ID_to_property(&ptr, prop);
		
		if (path) {
			/* set flags */
			if (all) {
				pflag |= KSP_FLAG_WHOLE_ARRAY;
				
				/* we need to set the index for this to 0, even though it may break in some cases, this is 
				 * necessary if we want the entire array for most cases to get included without the user
				 * having to worry about where they clicked
				 */
				index = 0;
			}
				
			/* add path to this setting */
			BKE_keyingset_add_path(ks, ptr.id.data, NULL, path, index, pflag, KSP_GROUP_KSNAME);
			ks->active_path = BLI_countlist(&ks->paths);
			success = 1;
			
			/* free the temp path created */
			MEM_freeN(path);
		}
	}
	
	if (success) {
		/* send updates */
		WM_event_add_notifier(C, NC_SCENE | ND_KEYINGSET, NULL);
		
		/* show notification/report header, so that users notice that something changed */
		BKE_reportf(op->reports, RPT_INFO, "Property added to Keying Set: '%s'", ks->name);
	}
	
	return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
}