예제 #1
0
/* Write into "name" buffer, the name of the property (retrieved using RNA from the curve's settings),
 * and return the icon used for the struct that this property refers to 
 * WARNING: name buffer we're writing to cannot exceed 256 chars (check anim_channels_defines.c for details)
 */
int getname_anim_fcurve(char *name, ID *id, FCurve *fcu)
{
	int icon = 0;
	
	/* sanity checks */
	if (name == NULL)
		return icon;
	else if (ELEM3(NULL, id, fcu, fcu->rna_path)) {
		if (fcu == NULL)
			strcpy(name, "<invalid>");
		else if (fcu->rna_path == NULL)
			strcpy(name, "<no path>");
		else /* id == NULL */
			BLI_snprintf(name, 256, "%s[%d]", fcu->rna_path, fcu->array_index);
	}
	else {
		PointerRNA id_ptr, ptr;
		PropertyRNA *prop;
		
		/* get RNA pointer, and resolve the path */
		RNA_id_pointer_create(id, &id_ptr);
		
		/* try to resolve the path */
		if (RNA_path_resolve(&id_ptr, fcu->rna_path, &ptr, &prop)) {
			const char *structname = NULL, *propname = NULL;
			char arrayindbuf[16];
			const char *arrayname = NULL;
			short free_structname = 0;
			
			/* For now, name will consist of 3 parts: struct-name, property name, array index
			 * There are several options possible:
			 *	1) <struct-name>.<property-name>.<array-index>
			 *		i.e. Bone1.Location.X, or Object.Location.X
			 *	2) <array-index> <property-name> (<struct name>)
			 *		i.e. X Location (Bone1), or X Location (Object)
			 *	
			 * Currently, option 2 is in use, to try and make it easier to quickly identify F-Curves (it does have
			 * problems with looking rather odd though). Option 1 is better in terms of revealing a consistent sense of 
			 * hierarchy though, which isn't so clear with option 2.
			 */
			
			/* for structname
			 *	- as base, we use a custom name from the structs if one is available 
			 *	- however, if we're showing subdata of bones (probably there will be other exceptions later)
			 *	  need to include that info too since it gets confusing otherwise
			 *	- if a pointer just refers to the ID-block, then don't repeat this info
			 *	  since this just introduces clutter
			 */
			if (strstr(fcu->rna_path, "bones") && strstr(fcu->rna_path, "constraints")) {
				/* perform string 'chopping' to get "Bone Name : Constraint Name" */
				char *pchanName = BLI_getQuotedStr(fcu->rna_path, "bones[");
				char *constName = BLI_getQuotedStr(fcu->rna_path, "constraints[");
				
				/* assemble the string to display in the UI... */
				structname = BLI_sprintfN("%s : %s", pchanName, constName);
				free_structname = 1;
				
				/* free the temp names */
				if (pchanName) MEM_freeN(pchanName);
				if (constName) MEM_freeN(constName);
			}
			else if (ptr.data != ptr.id.data) {
				PropertyRNA *nameprop = RNA_struct_name_property(ptr.type);
				if (nameprop) {
					/* this gets a string which will need to be freed */
					structname = RNA_property_string_get_alloc(&ptr, nameprop, NULL, 0, NULL);
					free_structname = 1;
				}
				else
					structname = RNA_struct_ui_name(ptr.type);
			}
			
			/* Property Name is straightforward */
			propname = RNA_property_ui_name(prop);
			
			/* Array Index - only if applicable */
			if (RNA_property_array_length(&ptr, prop)) {
				char c = RNA_property_array_item_char(prop, fcu->array_index);
				
				/* we need to write the index to a temp buffer (in py syntax) */
				if (c) BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "%c ", c);
				else BLI_snprintf(arrayindbuf, sizeof(arrayindbuf), "[%d]", fcu->array_index);
				
				arrayname = &arrayindbuf[0];
			}
			else {
				/* no array index */
				arrayname = "";
			}
			
			/* putting this all together into the buffer */
			// XXX we need to check for invalid names...
			// XXX the name length limit needs to be passed in or as some define
			if (structname)
				BLI_snprintf(name, 256, "%s%s (%s)", arrayname, propname, structname); 
			else
				BLI_snprintf(name, 256, "%s%s", arrayname, propname); 
			
			/* free temp name if nameprop is set */
			if (free_structname)
				MEM_freeN((void *)structname);
			
			
			/* Icon for this property's owner:
			 *	use the struct's icon if it is set
			 */
			icon = RNA_struct_ui_icon(ptr.type);
			
			/* valid path - remove the invalid tag since we now know how to use it saving
			 * users manual effort to reenable using "Revive Disabled FCurves" [#29629]
			 */
			fcu->flag &= ~FCURVE_DISABLED;
		}
		else {
			/* invalid path */
			BLI_snprintf(name, 256, "\"%s[%d]\"", fcu->rna_path, fcu->array_index);
			
			/* icon for this should be the icon for the base ID */
			// TODO: or should we just use the error icon?
			icon = RNA_struct_ui_icon(id_ptr.type);
			
			/* tag F-Curve as disabled - as not usable path */
			fcu->flag |= FCURVE_DISABLED;
		}
	}
	
	/* return the icon that the active data had */
	return icon;
}
예제 #2
0
/* perform syncing updates for F-Curves */
static void animchan_sync_fcurve (bAnimContext *UNUSED(ac), bAnimListElem *ale)
{
    FCurve *fcu= (FCurve *)ale->data;
    ID *owner_id= ale->id;

    /* major priority is selection status, so refer to the checks done in anim_filter.c
     * skip_fcurve_selected_data() for reference about what's going on here...
     */
    if (ELEM3(NULL, fcu, fcu->rna_path, owner_id))
        return;

    if (GS(owner_id->name) == ID_OB) {
        Object *ob= (Object *)owner_id;

        /* only affect if F-Curve involves pose.bones */
        if ((fcu->rna_path) && strstr(fcu->rna_path, "pose.bones")) {
            bPoseChannel *pchan;
            char *bone_name;

            /* get bone-name, and check if this bone is selected */
            bone_name= BLI_getQuotedStr(fcu->rna_path, "pose.bones[");
            pchan= get_pose_channel(ob->pose, bone_name);
            if (bone_name) MEM_freeN(bone_name);

            /* F-Curve selection depends on whether the bone is selected */
            if ((pchan) && (pchan->bone)) {
                if (pchan->bone->flag & BONE_SELECTED)
                    fcu->flag |= FCURVE_SELECTED;
                else
                    fcu->flag &= ~FCURVE_SELECTED;
            }
        }
    }
    else if (GS(owner_id->name) == ID_SCE) {
        Scene *scene = (Scene *)owner_id;

        /* only affect if F-Curve involves sequence_editor.sequences */
        if ((fcu->rna_path) && strstr(fcu->rna_path, "sequences_all")) {
            Editing *ed= seq_give_editing(scene, FALSE);
            Sequence *seq;
            char *seq_name;

            /* get strip name, and check if this strip is selected */
            seq_name= BLI_getQuotedStr(fcu->rna_path, "sequences_all[");
            seq = get_seq_by_name(ed->seqbasep, seq_name, FALSE);
            if (seq_name) MEM_freeN(seq_name);

            /* can only add this F-Curve if it is selected */
            if (seq) {
                if (seq->flag & SELECT)
                    fcu->flag |= FCURVE_SELECTED;
                else
                    fcu->flag &= ~FCURVE_SELECTED;
            }
        }
    }
    else if (GS(owner_id->name) == ID_NT) {
        bNodeTree *ntree = (bNodeTree *)owner_id;

        /* check for selected nodes */
        if ((fcu->rna_path) && strstr(fcu->rna_path, "nodes")) {
            bNode *node;
            char *node_name;

            /* get strip name, and check if this strip is selected */
            node_name= BLI_getQuotedStr(fcu->rna_path, "nodes[");
            node = nodeFindNodebyName(ntree, node_name);
            if (node_name) MEM_freeN(node_name);

            /* can only add this F-Curve if it is selected */
            if (node) {
                if (node->flag & NODE_SELECT)
                    fcu->flag |= FCURVE_SELECTED;
                else
                    fcu->flag &= ~FCURVE_SELECTED;
            }
        }
    }
}