/* 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; }
/* 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; } } } }