Allow renaming F-curve modifier #104949
@ -25,7 +25,7 @@ extern "C" {
|
||||
|
||||
/* Blender file format version. */
|
||||
#define BLENDER_FILE_VERSION BLENDER_VERSION
|
||||
#define BLENDER_FILE_SUBVERSION 5
|
||||
#define BLENDER_FILE_SUBVERSION 6
|
||||
|
||||
/* Minimum Blender version that supports reading file written with the current
|
||||
* version. Older Blender versions will test this and show a warning if the file
|
||||
|
@ -240,6 +240,10 @@ void BKE_fcurves_free(ListBase *list);
|
||||
*/
|
||||
void BKE_fcurves_copy(ListBase *dst, ListBase *src);
|
||||
|
||||
/* Set fcurve modifier name and ensure uniqueness.
|
||||
|
||||
* Pass new name string when it's been edited otherwise pass empty string. */
|
||||
Sybren A. Stüvel
commented
"its" → "it's been" "its" → "it's been"
|
||||
void BKE_fmodifier_name_set(struct FModifier *fcm, const char *name);
|
||||
|
||||
/**
|
||||
* Callback used by lib_query to walk over all ID usages
|
||||
* (mimics `foreach_id` callback of #IDTypeInfo structure).
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "BLI_ghash.h"
|
||||
#include "BLI_math.h"
|
||||
#include "BLI_sort_utils.h"
|
||||
#include "BLI_string_utils.h"
|
||||
|
||||
#include "BKE_anim_data.h"
|
||||
#include "BKE_animsys.h"
|
||||
@ -157,6 +158,18 @@ void BKE_fcurves_copy(ListBase *dst, ListBase *src)
|
||||
}
|
||||
}
|
||||
|
||||
void BKE_fmodifier_name_set(FModifier *fcm, const char *name)
|
||||
{
|
||||
/* Copy new Modifier name. */
|
||||
BLI_strncpy(fcm->name, name, sizeof(fcm->name));
|
||||
|
||||
/* Set default modifier name when name parameter is an empty string.
|
||||
* Ensure the name is unique. */
|
||||
const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(fcm->type);
|
||||
ListBase list = BLI_listbase_from_link((Link *)fcm);
|
||||
BLI_uniquename(&list, fcm, fmi->name, '.', offsetof(FModifier, name), sizeof(fcm->name));
|
||||
}
|
||||
|
||||
void BKE_fcurve_foreach_id(FCurve *fcu, LibraryForeachIDData *data)
|
||||
{
|
||||
ChannelDriver *driver = fcu->driver;
|
||||
|
@ -1109,6 +1109,9 @@ FModifier *add_fmodifier(ListBase *modifiers, int type, FCurve *owner_fcu)
|
||||
fcm->influence = 1.0f;
|
||||
BLI_addtail(modifiers, fcm);
|
||||
|
||||
/* Set modifier name and make sure it is unique. */
|
||||
Sybren A. Stüvel
commented
This comment just basically repeats the function name. It would be better to explain why this is done here: to ensure the name is unique within the list of modifiers, it can only be set after it has been added to the list. This comment just basically repeats the function name. It would be better to explain *why* this is done here: to ensure the name is unique within the list of modifiers, it can only be set *after* it has been added to the list.
|
||||
BKE_fmodifier_name_set(fcm, "");
|
||||
Sybren A. Stüvel
commented
This should be using This should be using `sizeof(fcm->name)`; the limit should be determined by the available memory to copy **into**. Same for similar calls below.
|
||||
|
||||
/* tag modifier as "active" if no other modifiers exist in the stack yet */
|
||||
if (BLI_listbase_is_single(modifiers)) {
|
||||
Sybren A. Stüvel
commented
I think a function call That function would also need to have some documentation about how it would behave when there already is a modifier with the given name. Would it change the name of I think a function call `BKE_fmodifier_name_set(fcm, fmi->name)` would be preferrable. That could combine the `BLI_strncpy()` and the `BLI_uniquename()` calls, and give the caller a one-stop-shop for setting the modifier name. That way the caller doesn't need to know anything about the `FModifier` struct; limiting required knowledge is often a good idea.
That function would also need to have some documentation about how it would behave when there already is a modifier with the given name. Would it change the name of `fcm` to become unique? Or of the other modifier with that same name?
|
||||
fcm->flag |= FMODIFIER_FLAG_ACTIVE;
|
||||
|
@ -4283,6 +4283,19 @@ void blo_do_versions_300(FileData *fd, Library * /*lib*/, Main *bmain)
|
||||
}
|
||||
}
|
||||
|
||||
/* fcm->name was never used to store modifier name so it has always been an empty string. Now
|
||||
* this property supports name editing. So assign value to name variable of Fmodifier otherwise
|
||||
Sybren A. Stüvel
commented
It's unclear how calling If this triggers some kind of special behaviour of It's unclear how calling `BKE_fmodifier_name_set(fcm, "")` (so with an empty `name` parameter) would avoid modifiers having an empty name.
If this triggers some kind of special behaviour of `BKE_fmodifier_name_set()`, that should be mentioned in that function's documentation.
Pratik Borhade
commented
Updated code comments. This is handled within BLI_uniquename (see defname parameter). > It's unclear how calling BKE_fmodifier_name_set(fcm, "") (so with an empty name parameter) would avoid modifiers having an empty name.
Updated code comments. This is handled within BLI_uniquename (see defname parameter).
|
||||
* modifier interface would show an empty name field. Also ensure uniqueness when opening old
|
||||
* files. */
|
||||
if (!MAIN_VERSION_ATLEAST(bmain, 306, 6)) {
|
||||
LISTBASE_FOREACH (bAction *, act, &bmain->actions) {
|
||||
LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
|
||||
LISTBASE_FOREACH (FModifier *, fcm, &fcu->modifiers) {
|
||||
BKE_fmodifier_name_set(fcm, "");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Versioning code until next subversion bump goes here.
|
||||
*
|
||||
|
@ -303,20 +303,17 @@ static void fmodifier_panel_header(const bContext *C, Panel *panel)
|
||||
uiBlock *block = uiLayoutGetBlock(layout);
|
||||
|
||||
uiLayout *sub = uiLayoutRow(layout, true);
|
||||
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
|
||||
uiLayoutSetEmboss(sub, UI_EMBOSS_NONE);
|
||||
|
||||
/* Checkbox for 'active' status (for now). */
|
||||
uiItemR(sub, ptr, "active", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
|
||||
|
||||
/* Name. */
|
||||
if (fmi) {
|
||||
uiItemL(sub, IFACE_(fmi->name), ICON_NONE);
|
||||
uiItemR(sub, ptr, "name", 0, "", ICON_NONE);
|
||||
}
|
||||
else {
|
||||
uiItemL(sub, IFACE_("<Unknown Modifier>"), ICON_NONE);
|
||||
}
|
||||
|
||||
/* Right align. */
|
||||
Sybren A. Stüvel
commented
Panel drawing code shouldn't alter the drawn information. If Panel drawing code shouldn't alter the drawn information. If `fcm->name` must be set, do so in the appropriate place.
Pratik Borhade
commented
Hi, sorry for the late update. Included all fixes in branch expect this one. > When opening a file, that already had an fcurve modifier prior to the patch, the name field is empty
Hi, sorry for the late update. Included all fixes in branch expect this one.
I'm not sure what would be the correct place to set `fcm->name`.
Any clue?
|
||||
sub = uiLayoutRow(layout, true);
|
||||
uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
|
||||
|
@ -838,6 +838,12 @@ static void rna_FModifier_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *
|
||||
rna_tag_animation_update(bmain, id);
|
||||
}
|
||||
|
||||
static void rna_fModifier_name_set(PointerRNA *ptr, const char *value)
|
||||
{
|
||||
FModifier *fcm = (FModifier *)ptr->data;
|
||||
BKE_fmodifier_name_set(fcm, value);
|
||||
}
|
||||
|
||||
static void rna_FModifier_verify_data_update(Main *bmain, Scene *scene, PointerRNA *ptr)
|
||||
{
|
||||
FModifier *fcm = (FModifier *)ptr->data;
|
||||
@ -1742,12 +1748,12 @@ static void rna_def_fmodifier(BlenderRNA *brna)
|
||||
RNA_def_struct_refine_func(srna, "rna_FModifierType_refine");
|
||||
RNA_def_struct_ui_text(srna, "F-Modifier", "Modifier for values of F-Curve");
|
||||
|
||||
# if 0 /* XXX not used yet */
|
||||
/* name */
|
||||
prop = RNA_def_property(srna, "name", PROP_STRING, PROP_NONE);
|
||||
RNA_def_property_string_funcs(prop, NULL, NULL, "rna_fModifier_name_set");
|
||||
RNA_def_property_ui_text(prop, "Name", "F-Curve Modifier name");
|
||||
RNA_def_property_update(prop, NC_OBJECT | ND_MODIFIER | NA_RENAME, NULL);
|
||||
RNA_def_struct_name_property(srna, prop);
|
||||
RNA_def_property_ui_text(prop, "Name", "Short description of F-Curve Modifier");
|
||||
# endif /* XXX not used yet */
|
||||
|
||||
/* type */
|
||||
prop = RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE);
|
||||
|
"check" → "ensure"
To "check" doesn't necessarily imply that this uniqueness is ensured. It could also just return a boolean. And the return type of the function shouldn't be necessary to understand its documentation.