Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source/blender/blenkernel/intern/fmodifier.c3
-rw-r--r--source/blender/blenloader/intern/versioning_290.c13
-rw-r--r--source/blender/editors/animation/fmodifier_ui.c1449
-rw-r--r--source/blender/editors/include/ED_anim_api.h28
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c37
-rw-r--r--source/blender/editors/space_nla/nla_buttons.c37
-rw-r--r--source/blender/makesdna/DNA_anim_types.h11
-rw-r--r--source/blender/makesrna/intern/rna_fcurve.c21
8 files changed, 800 insertions, 799 deletions
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index d0018a556ba..4cd49987a83 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -32,6 +32,7 @@
#include "CLG_log.h"
#include "DNA_anim_types.h"
+#include "DNA_screen_types.h"
#include "BLT_translation.h"
@@ -1133,7 +1134,7 @@ FModifier *add_fmodifier(ListBase *modifiers, int type, FCurve *owner_fcu)
/* add modifier itself */
fcm = MEM_callocN(sizeof(FModifier), "F-Curve Modifier");
fcm->type = type;
- fcm->flag = FMODIFIER_FLAG_EXPANDED;
+ fcm->ui_expand_flag = UI_PANEL_DATA_EXPAND_ROOT; /* Expand the main panel, not the subpanels. */
fcm->curve = owner_fcu;
fcm->influence = 1.0f;
BLI_addtail(modifiers, fcm);
diff --git a/source/blender/blenloader/intern/versioning_290.c b/source/blender/blenloader/intern/versioning_290.c
index 089886a1c25..728235e84bf 100644
--- a/source/blender/blenloader/intern/versioning_290.c
+++ b/source/blender/blenloader/intern/versioning_290.c
@@ -1748,6 +1748,19 @@ void blo_do_versions_290(FileData *fd, Library *UNUSED(lib), Main *bmain)
}
}
+ /* Add subpanels for FModifiers, which requires a field to store expansion. */
+ if (!DNA_struct_elem_find(fd->filesdna, "FModifier", "short", "ui_expand_flag")) {
+ LISTBASE_FOREACH (bAction *, act, &bmain->actions) {
+ LISTBASE_FOREACH (FCurve *, fcu, &act->curves) {
+ LISTBASE_FOREACH (FModifier *, fcm, &fcu->modifiers) {
+ SET_FLAG_FROM_TEST(fcm->ui_expand_flag,
+ fcm->flag & FMODIFIER_FLAG_EXPANDED,
+ UI_PANEL_DATA_EXPAND_ROOT);
+ }
+ }
+ }
+ }
+
/* Keep this block, even when empty. */
}
}
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index deebf1d1efc..c17d678d866 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -32,6 +32,7 @@
#include "DNA_anim_types.h"
#include "DNA_scene_types.h"
+#include "DNA_space_types.h"
#include "MEM_guardedalloc.h"
@@ -42,6 +43,7 @@
#include "BKE_context.h"
#include "BKE_fcurve.h"
+#include "BKE_screen.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -56,47 +58,208 @@
#include "DEG_depsgraph.h"
-/* ********************************************** */
-/* UI STUFF */
+typedef void (*PanelDrawFn)(const bContext *, struct Panel *);
+static void fmodifier_panel_header(const bContext *C, Panel *panel);
-/* XXX! -------------------------------- */
-/* Temporary definition for limits of float number buttons
- * (FLT_MAX tends to infinity with old system). */
-#define UI_FLT_MAX 10000.0f
+/* -------------------------------------------------------------------- */
+/** \name Panel Registering and Panel Callbacks
+ * \{ */
-#define B_REDR 1
-#define B_FMODIFIER_REDRAW 20
+/**
+ * Get the list of FModifiers from the context (either the NLA or graph editor).
+ */
+static ListBase *fmodifier_list_space_specific(const bContext *C)
+{
+ ScrArea *area = CTX_wm_area(C);
+
+ if (area->spacetype == SPACE_GRAPH) {
+ FCurve *fcu = ANIM_graph_context_fcurve(C);
+ return &fcu->modifiers;
+ }
+
+ if (area->spacetype == SPACE_NLA) {
+ NlaStrip *strip = ANIM_nla_context_strip(C);
+ return &strip->modifiers;
+ }
-/* callback to update depsgraph on value changes */
-static void deg_update(bContext *C, void *owner_id, void *UNUSED(var2))
+ /* This should not be called in any other space. */
+ BLI_assert(false);
+ return NULL;
+}
+
+/**
+ * Get a pointer to the panel's FModifier, and also its owner ID if \a r_owner_id is not NULL.
+ * Also in the graph editor, gray out the panel if the FModifier's FCurve has modifiers turned off.
+ */
+static PointerRNA *fmodifier_get_pointers(const bContext *C, const Panel *panel, ID **r_owner_id)
{
- /* send notifiers */
- /* XXX for now, this is the only way to get updates in all the right places...
- * but would be nice to have a special one in this case. */
- WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
- DEG_id_tag_update(owner_id, ID_RECALC_ANIMATION);
+ PointerRNA *ptr = UI_panel_custom_data_get(panel);
+
+ if (r_owner_id != NULL) {
+ *r_owner_id = ptr->owner_id;
+ }
+
+ if (C != NULL && CTX_wm_space_graph(C)) {
+ FCurve *fcu = ANIM_graph_context_fcurve(C);
+ uiLayoutSetActive(panel->layout, !(fcu->flag & FCURVE_MOD_OFF));
+ }
+
+ return ptr;
}
-/* callback to verify modifier data */
-static void validate_fmodifier_cb(bContext *C, void *fcm_v, void *owner_id)
+/**
+ * Move an FModifier to the index it's moved to after a drag and drop.
+ */
+static void fmodifier_reorder(bContext *C, Panel *panel, int new_index)
{
- FModifier *fcm = (FModifier *)fcm_v;
- const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
+ ID *owner_id;
+ PointerRNA *ptr = fmodifier_get_pointers(NULL, panel, &owner_id);
+ FModifier *fcm = ptr->data;
+ const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(fcm->type);
+
+ /* Cycles modifier has to be the first, so make sure it's kept that way. */
+ if (fmi->requires & FMI_REQUIRES_ORIGINAL_DATA) {
+ WM_report(RPT_ERROR, "Modifier requires original data");
+ return;
+ }
- /* call the verify callback on the modifier if applicable */
- if (fmi && fmi->verify_data) {
- fmi->verify_data(fcm);
+ ListBase *modifiers = fmodifier_list_space_specific(C);
+
+ /* Again, make sure we don't move a modifier before a cycles modifier. */
+ FModifier *fcm_first = modifiers->first;
+ const FModifierTypeInfo *fmi_first = get_fmodifier_typeinfo(fcm_first->type);
+ if (fmi_first->requires & FMI_REQUIRES_ORIGINAL_DATA && new_index == 0) {
+ WM_report(RPT_ERROR, "Modifier requires original data");
+ return;
}
- if (owner_id) {
- deg_update(C, owner_id, NULL);
+
+ int current_index = BLI_findindex(modifiers, fcm);
+ BLI_assert(current_index >= 0);
+ BLI_assert(new_index >= 0);
+
+ /* Don't do anything if the drag didn't change the index. */
+ if (current_index == new_index) {
+ return;
}
+
+ /* Move the FModifier in the list. */
+ BLI_listbase_link_move(modifiers, fcm, new_index - current_index);
+
+ ED_undo_push(C, "Reorder F-Curve Modifier");
+
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ DEG_id_tag_update(owner_id, ID_RECALC_ANIMATION);
+}
+
+static short get_fmodifier_expand_flag(const bContext *UNUSED(C), Panel *panel)
+{
+ PointerRNA *ptr = fmodifier_get_pointers(NULL, panel, NULL);
+ FModifier *fcm = (FModifier *)ptr->data;
+
+ return fcm->ui_expand_flag;
+}
+
+static void set_fmodifier_expand_flag(const bContext *UNUSED(C), Panel *panel, short expand_flag)
+{
+ PointerRNA *ptr = fmodifier_get_pointers(NULL, panel, NULL);
+ FModifier *fcm = (FModifier *)ptr->data;
+
+ fcm->ui_expand_flag = expand_flag;
+}
+
+static PanelType *fmodifier_panel_register(ARegionType *region_type,
+ eFModifier_Types type,
+ PanelDrawFn draw,
+ PanelTypePollFn poll,
+ const char *id_prefix)
+{
+ /* Get the name for the modifier's panel. */
+ char panel_idname[BKE_ST_MAXNAME];
+ const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(type);
+ BLI_snprintf(panel_idname, BKE_ST_MAXNAME, "%s_PT_%s", id_prefix, fmi->name);
+
+ PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
+
+ /* Intentionally leave the label field blank. The header is filled with buttons. */
+ BLI_strncpy(panel_type->idname, panel_idname, BKE_ST_MAXNAME);
+ BLI_strncpy(panel_type->category, "Modifiers", BKE_ST_MAXNAME);
+ BLI_strncpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA, BKE_ST_MAXNAME);
+
+ panel_type->draw_header = fmodifier_panel_header;
+ panel_type->draw = draw;
+ panel_type->poll = poll;
+
+ /* Give the panel the special flag that says it was built here and corresponds to a
+ * modifer rather than a PanelType. */
+ panel_type->flag = PANEL_TYPE_HEADER_EXPAND | PANEL_TYPE_DRAW_BOX | PANEL_TYPE_INSTANCED;
+ panel_type->reorder = fmodifier_reorder;
+ panel_type->get_list_data_expand_flag = get_fmodifier_expand_flag;
+ panel_type->set_list_data_expand_flag = set_fmodifier_expand_flag;
+
+ BLI_addtail(&region_type->paneltypes, panel_type);
+
+ return panel_type;
}
+/**
+ * Add a child panel to the parent.
+ *
+ * \note To create the panel type's idname, it appends the \a name argument to the \a parent's
+ * idname.
+ */
+static PanelType *fmodifier_subpanel_register(ARegionType *region_type,
+ const char *name,
+ const char *label,
+ PanelDrawFn draw_header,
+ PanelDrawFn draw,
+ PanelTypePollFn poll,
+ PanelType *parent)
+{
+ /* Create the subpanel's ID name. */
+ char panel_idname[BKE_ST_MAXNAME];
+ BLI_snprintf(panel_idname, BKE_ST_MAXNAME, "%s_%s", parent->idname, name);
+
+ PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
+
+ BLI_strncpy(panel_type->idname, panel_idname, BKE_ST_MAXNAME);
+ BLI_strncpy(panel_type->label, label, BKE_ST_MAXNAME);
+ BLI_strncpy(panel_type->category, "Modifiers", BKE_ST_MAXNAME);
+ BLI_strncpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA, BKE_ST_MAXNAME);
+
+ panel_type->draw_header = draw_header;
+ panel_type->draw = draw;
+ panel_type->poll = poll;
+ panel_type->flag = PANEL_TYPE_DEFAULT_CLOSED | PANEL_TYPE_DRAW_BOX;
+
+ BLI_assert(parent != NULL);
+ BLI_strncpy(panel_type->parent_id, parent->idname, BKE_ST_MAXNAME);
+ panel_type->parent = parent;
+ BLI_addtail(&parent->children, BLI_genericNodeN(panel_type));
+ BLI_addtail(&region_type->paneltypes, panel_type);
+
+ return panel_type;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name General UI Callbacks and Drawing
+ * \{ */
+
+/* XXX! -------------------------------- */
+/* Temporary definition for limits of float number buttons
+ * (FLT_MAX tends to infinity with old system). */
+#define UI_FLT_MAX 10000.0f
+
+#define B_REDR 1
+#define B_FMODIFIER_REDRAW 20
+
/* callback to remove the given modifier */
typedef struct FModifierDeleteContext {
- ID *fcurve_owner_id;
+ ID *owner_id;
ListBase *modifiers;
} FModifierDeleteContext;
+
static void delete_fmodifier_cb(bContext *C, void *ctx_v, void *fcm_v)
{
FModifierDeleteContext *ctx = (FModifierDeleteContext *)ctx_v;
@@ -108,466 +271,334 @@ static void delete_fmodifier_cb(bContext *C, void *ctx_v, void *fcm_v)
ED_undo_push(C, "Delete F-Curve Modifier");
- deg_update(C, ctx->fcurve_owner_id, NULL);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ DEG_id_tag_update(ctx->owner_id, ID_RECALC_ANIMATION);
}
-/* --------------- */
-/* draw settings for generator modifier */
-static void draw_modifier__generator(uiLayout *layout,
- ID *fcurve_owner_id,
- FModifier *fcm,
- short width)
+static void fmodifier_influence_draw(uiLayout *layout, PointerRNA *ptr)
{
+ FModifier *fcm = (FModifier *)ptr->data;
+ uiItemS(layout);
+
+ uiLayout *row = uiLayoutRowWithHeading(layout, true, IFACE_("Influence"));
+ uiItemR(row, ptr, "use_influence", 0, "", ICON_NONE);
+ uiLayout *sub = uiLayoutRow(row, true);
+
+ uiLayoutSetActive(sub, fcm->flag & FMODIFIER_FLAG_USEINFLUENCE);
+ uiItemR(sub, ptr, "influence", 0, "", ICON_NONE);
+}
+
+static void fmodifier_frame_range_header_draw(const bContext *C, Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+
+ PointerRNA *ptr = fmodifier_get_pointers(C, panel, NULL);
+
+ uiItemR(layout, ptr, "use_restricted_range", 0, NULL, ICON_NONE);
+}
+
+static void fmodifier_frame_range_draw(const bContext *C, Panel *panel)
+{
+ uiLayout *col;
+ uiLayout *layout = panel->layout;
+
+ PointerRNA *ptr = fmodifier_get_pointers(C, panel, NULL);
+
+ uiLayoutSetPropSep(layout, true);
+
+ FModifier *fcm = (FModifier *)ptr->data;
+ uiLayoutSetActive(layout, fcm->flag & FMODIFIER_FLAG_RANGERESTRICT);
+
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, ptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
+ uiItemR(col, ptr, "frame_end", 0, IFACE_("End"), ICON_NONE);
+
+ col = uiLayoutColumn(layout, true);
+ uiItemR(col, ptr, "blend_in", 0, IFACE_("Blend In"), ICON_NONE);
+ uiItemR(col, ptr, "blend_out", 0, IFACE_("Out"), ICON_NONE);
+}
+
+static void fmodifier_panel_header(const bContext *C, Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+
+ ID *owner_id;
+ PointerRNA *ptr = fmodifier_get_pointers(C, panel, &owner_id);
+ FModifier *fcm = (FModifier *)ptr->data;
+ const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
+
+ 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);
+ }
+ else {
+ uiItemL(sub, IFACE_("<Unknown Modifier>"), ICON_NONE);
+ }
+
+ /* Right align. */
+ sub = uiLayoutRow(layout, true);
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
+ uiLayoutSetEmboss(sub, UI_EMBOSS_NONE);
+
+ /* 'Mute' button. */
+ uiItemR(sub, ptr, "mute", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+
+ /* Delete button. */
+ uiBut *but = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ B_REDR,
+ ICON_X,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ TIP_("Delete Modifier"));
+ FModifierDeleteContext *ctx = MEM_mallocN(sizeof(FModifierDeleteContext), __func__);
+ ctx->owner_id = owner_id;
+ ctx->modifiers = fmodifier_list_space_specific(C);
+ BLI_assert(ctx->modifiers != NULL);
+
+ UI_but_funcN_set(but, delete_fmodifier_cb, ctx, fcm);
+
+ uiItemS(layout);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Generator Modifier
+ * \{ */
+
+static void generator_panel_draw(const bContext *C, Panel *panel)
+{
+ uiLayout *layout = panel->layout;
+
+ ID *owner_id;
+ PointerRNA *ptr = fmodifier_get_pointers(C, panel, &owner_id);
+ FModifier *fcm = (FModifier *)ptr->data;
FMod_Generator *data = (FMod_Generator *)fcm->data;
- uiLayout /* *col, */ /* UNUSED */ *row;
- uiBlock *block;
- uiBut *but;
- PointerRNA ptr;
- short bwidth = width - 1.5 * UI_UNIT_X; /* max button width */
-
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
-
- /* basic settings (backdrop + mode selector + some padding) */
- /* col = uiLayoutColumn(layout, true); */ /* UNUSED */
- block = uiLayoutGetBlock(layout);
- UI_block_align_begin(block);
- but = uiDefButR(block,
- UI_BTYPE_MENU,
- B_FMODIFIER_REDRAW,
- NULL,
- 0,
- 0,
- bwidth,
- UI_UNIT_Y,
- &ptr,
- "mode",
- -1,
- 0,
- 0,
- -1,
- -1,
- NULL);
- UI_but_func_set(but, validate_fmodifier_cb, fcm, NULL);
-
- uiDefButR(block,
- UI_BTYPE_TOGGLE,
- B_FMODIFIER_REDRAW,
- NULL,
- 0,
- 0,
- bwidth,
- UI_UNIT_Y,
- &ptr,
- "use_additive",
- -1,
- 0,
- 0,
- -1,
- -1,
- NULL);
- UI_block_align_end(block);
-
- /* now add settings for individual modes */
+
+ uiItemR(layout, ptr, "mode", 0, "", ICON_NONE);
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
+ uiItemR(layout, ptr, "use_additive", 0, NULL, ICON_NONE);
+
+ uiItemR(layout, ptr, "poly_order", 0, IFACE_("Order"), ICON_NONE);
+
+ PropertyRNA *prop = RNA_struct_find_property(ptr, "coefficients");
+ uiLayout *col = uiLayoutColumn(layout, true);
switch (data->mode) {
- case FCM_GENERATOR_POLYNOMIAL: /* polynomial expression */
+ case FCM_GENERATOR_POLYNOMIAL: /* Polynomial expression. */
{
- const uiFontStyle *fstyle = UI_FSTYLE_WIDGET;
- float *cp = NULL;
+
char xval[32];
- int maxXWidth;
-
- /* draw polynomial order selector */
- row = uiLayoutRow(layout, false);
- block = uiLayoutGetBlock(row);
-
- but = uiDefButI(
- block,
- UI_BTYPE_NUM,
- B_FMODIFIER_REDRAW,
- IFACE_("Poly Order:"),
- 0.5f * UI_UNIT_X,
- 0,
- bwidth,
- UI_UNIT_Y,
- &data->poly_order,
- 1,
- 100,
- 0,
- 0,
- TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
- UI_but_number_step_size_set(but, 1);
- UI_but_func_set(but, validate_fmodifier_cb, fcm, fcurve_owner_id);
-
- /* calculate maximum width of label for "x^n" labels */
- if (data->arraysize > 2) {
- BLI_snprintf(xval, sizeof(xval), "x^%u", data->arraysize);
- /* XXX: UI_fontstyle_string_width is not accurate */
- maxXWidth = UI_fontstyle_string_width(fstyle, xval) + 0.5 * UI_UNIT_X;
- }
- else {
- /* basic size (just "x") */
- maxXWidth = UI_fontstyle_string_width(fstyle, "x") + 0.5 * UI_UNIT_X;
- }
- /* draw controls for each coefficient and a + sign at end of row */
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
-
- /* Update depsgraph when values change */
- UI_block_func_set(block, deg_update, fcurve_owner_id, NULL);
-
- cp = data->coefficients;
- for (uint i = 0; (i < data->arraysize) && (cp); i++, cp++) {
- /* To align with first line... */
- if (i) {
- uiDefBut(block,
- UI_BTYPE_LABEL,
- 1,
- " ",
- 0,
- 0,
- 2 * UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0,
- 0,
- "");
- }
- else {
- uiDefBut(block,
- UI_BTYPE_LABEL,
- 1,
- "y =",
- 0,
- 0,
- 2 * UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0,
- 0,
- "");
- }
-
- /* coefficient */
- but = uiDefButF(block,
- UI_BTYPE_NUM,
- B_FMODIFIER_REDRAW,
- "",
- 0,
- 0,
- bwidth / 2,
- UI_UNIT_Y,
- cp,
- -UI_FLT_MAX,
- UI_FLT_MAX,
- 0,
- 0,
- TIP_("Coefficient for polynomial"));
- UI_but_number_step_size_set(but, 10);
- UI_but_number_precision_set(but, 3);
-
- /* 'x' param (and '+' if necessary) */
- if (i == 0) {
- BLI_strncpy(xval, " ", sizeof(xval));
- }
- else if (i == 1) {
- BLI_strncpy(xval, "x", sizeof(xval));
- }
- else {
- BLI_snprintf(xval, sizeof(xval), "x^%u", i);
- }
- uiDefBut(block,
- UI_BTYPE_LABEL,
- 1,
- xval,
- 0,
- 0,
- maxXWidth,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0,
- 0,
- TIP_("Power of x"));
-
- if ((i != (data->arraysize - 1)) || ((i == 0) && data->arraysize == 2)) {
- uiDefBut(
- block, UI_BTYPE_LABEL, 1, "+", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
- /* next coefficient on a new row */
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
- }
- else {
- /* For alignment in UI! */
- uiDefBut(
- block, UI_BTYPE_LABEL, 1, " ", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
- }
+ /* The first value gets a "Coefficient" label. */
+ BLI_strncpy(xval, "Coefficient", sizeof(xval));
+
+ for (int i = 0; i < data->arraysize; i++) {
+ uiItemFullR(col, ptr, prop, i, 0, 0, N_(xval), ICON_NONE);
+ BLI_snprintf(xval, sizeof(xval), "x^%d", i + 1);
}
break;
}
-
case FCM_GENERATOR_POLYNOMIAL_FACTORISED: /* Factorized polynomial expression */
{
- float *cp = NULL;
-
- /* draw polynomial order selector */
- row = uiLayoutRow(layout, false);
- block = uiLayoutGetBlock(row);
-
- but = uiDefButI(
- block,
- UI_BTYPE_NUM,
- B_FMODIFIER_REDRAW,
- IFACE_("Poly Order:"),
- 0,
- 0,
- width - 1.5 * UI_UNIT_X,
- UI_UNIT_Y,
- &data->poly_order,
- 1,
- 100,
- 0,
- 0,
- TIP_("'Order' of the Polynomial (for a polynomial with n terms, 'order' is n-1)"));
- UI_but_func_set(but, validate_fmodifier_cb, fcm, fcurve_owner_id);
- UI_but_number_step_size_set(but, 1);
-
- /* draw controls for each pair of coefficients */
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
-
- /* Update depsgraph when values change */
- UI_block_func_set(block, deg_update, fcurve_owner_id, NULL);
-
- cp = data->coefficients;
- for (uint i = 0; (i < data->poly_order) && (cp); i++, cp += 2) {
- /* To align with first line */
- if (i) {
- uiDefBut(block,
- UI_BTYPE_LABEL,
- 1,
- " ",
- 0,
- 0,
- 2.5 * UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0,
- 0,
- "");
- }
- else {
- uiDefBut(block,
- UI_BTYPE_LABEL,
- 1,
- "y =",
- 0,
- 0,
- 2.5 * UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0,
- 0,
- "");
- }
- /* opening bracket */
- uiDefBut(
- block, UI_BTYPE_LABEL, 1, "(", 0, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "");
-
- /* coefficients */
- but = uiDefButF(block,
- UI_BTYPE_NUM,
- B_FMODIFIER_REDRAW,
- "",
- 0,
- 0,
- 5 * UI_UNIT_X,
- UI_UNIT_Y,
- cp,
- -UI_FLT_MAX,
- UI_FLT_MAX,
- 0,
- 0,
- TIP_("Coefficient of x"));
- UI_but_number_step_size_set(but, 10);
- UI_but_number_precision_set(but, 3);
-
- uiDefBut(block,
- UI_BTYPE_LABEL,
- 1,
- "x +",
- 0,
- 0,
- 2 * UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0,
- 0,
- "");
-
- but = uiDefButF(block,
- UI_BTYPE_NUM,
- B_FMODIFIER_REDRAW,
- "",
- 0,
- 0,
- 5 * UI_UNIT_X,
- UI_UNIT_Y,
- cp + 1,
- -UI_FLT_MAX,
- UI_FLT_MAX,
- 0,
- 0,
- TIP_("Second coefficient"));
- UI_but_number_step_size_set(but, 10);
- UI_but_number_precision_set(but, 3);
-
- /* closing bracket and multiplication sign */
- if ((i != (data->poly_order - 1)) || ((i == 0) && data->poly_order == 2)) {
- uiDefBut(block,
- UI_BTYPE_LABEL,
- 1,
- ") \xc3\x97",
- 0,
- 0,
- 2 * UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0,
- 0,
- "");
-
- /* set up new row for the next pair of coefficients */
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
- }
- else {
- uiDefBut(block,
- UI_BTYPE_LABEL,
- 1,
- ") ",
- 0,
- 0,
- 2 * UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0,
- 0,
- "");
- }
+ {
+ /* Add column labels above the buttons to prevent confusion.
+ * Fake the property split layout, otherwise the labels use the full row. */
+ uiLayout *split = uiLayoutSplit(col, 0.4f, false);
+ uiLayoutColumn(split, false);
+ uiLayout *title_col = uiLayoutColumn(split, false);
+ uiLayout *title_row = uiLayoutRow(title_col, true);
+ uiItemL(title_row, N_("A"), ICON_NONE);
+ uiItemL(title_row, N_("B"), ICON_NONE);
+ }
+
+ uiLayout *first_row = uiLayoutRow(col, true);
+ uiItemFullR(first_row, ptr, prop, 0, 0, 0, N_("y = (Ax + B)"), ICON_NONE);
+ uiItemFullR(first_row, ptr, prop, 1, 0, 0, "", ICON_NONE);
+ for (int i = 2; i < data->arraysize - 1; i++) {
+ /* \u2715 is the multiplication symbol. */
+ uiLayout *row = uiLayoutRow(col, true);
+ uiItemFullR(row, ptr, prop, i, 0, 0, N_("\u2715 (Ax + B)"), ICON_NONE);
+ uiItemFullR(row, ptr, prop, i + 1, 0, 0, "", ICON_NONE);
}
break;
}
}
+
+ fmodifier_influence_draw(layout, ptr);
}
-/* --------------- */
+static void panel_register_generator(ARegionType *region_type,
+ const char *id_prefix,
+ PanelTypePollFn poll_fn)
+{
+ PanelType *panel_type = fmodifier_panel_register(
+ region_type, FMODIFIER_TYPE_GENERATOR, generator_panel_draw, poll_fn, id_prefix);
+ fmodifier_subpanel_register(region_type,
+ "frame_range",
+ "",
+ fmodifier_frame_range_header_draw,
+ fmodifier_frame_range_draw,
+ poll_fn,
+ panel_type);
+}
+
+/** \} */
-/* draw settings for generator modifier */
-static void draw_modifier__fn_generator(uiLayout *layout,
- ID *fcurve_owner_id,
- FModifier *fcm,
- short UNUSED(width))
+/* -------------------------------------------------------------------- */
+/** \name Function Generator Modifier
+ * \{ */
+
+static void fn_generator_panel_draw(const bContext *C, Panel *panel)
{
uiLayout *col;
- PointerRNA ptr;
+ uiLayout *layout = panel->layout;
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierFunctionGenerator, fcm, &ptr);
+ PointerRNA *ptr = fmodifier_get_pointers(C, panel, NULL);
- /* add the settings */
- col = uiLayoutColumn(layout, true);
- uiItemR(col, &ptr, "function_type", 0, "", ICON_NONE);
- uiItemR(col, &ptr, "use_additive", UI_ITEM_R_TOGGLE, NULL, ICON_NONE);
-
- col = uiLayoutColumn(layout, false); /* no grouping for now */
- uiItemR(col, &ptr, "amplitude", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "phase_multiplier", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "phase_offset", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "value_offset", 0, NULL, ICON_NONE);
+ uiItemR(layout, ptr, "function_type", 0, "", ICON_NONE);
+
+ uiLayoutSetPropSep(layout, true);
+
+ col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "use_additive", 0, NULL, ICON_NONE);
+
+ col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "amplitude", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "phase_multiplier", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "phase_offset", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "value_offset", 0, NULL, ICON_NONE);
+
+ fmodifier_influence_draw(layout, ptr);
}
-/* --------------- */
+static void panel_register_fn_generator(ARegionType *region_type,
+ const char *id_prefix,
+ PanelTypePollFn poll_fn)
+{
+ PanelType *panel_type = fmodifier_panel_register(
+ region_type, FMODIFIER_TYPE_FN_GENERATOR, fn_generator_panel_draw, poll_fn, id_prefix);
+ fmodifier_subpanel_register(region_type,
+ "frame_range",
+ "",
+ fmodifier_frame_range_header_draw,
+ fmodifier_frame_range_draw,
+ poll_fn,
+ panel_type);
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Cycles Modifier
+ * \{ */
+
+static void cycles_panel_draw(const bContext *C, Panel *panel)
+{
+ uiLayout *col;
+ uiLayout *layout = panel->layout;
+
+ PointerRNA *ptr = fmodifier_get_pointers(C, panel, NULL);
+
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
+
+ /* Before. */
+ col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "mode_before", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "cycles_before", 0, IFACE_("Count"), ICON_NONE);
+
+ /* After. */
+ col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "mode_after", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "cycles_after", 0, IFACE_("Count"), ICON_NONE);
+
+ fmodifier_influence_draw(layout, ptr);
+}
-/* draw settings for cycles modifier */
-static void draw_modifier__cycles(uiLayout *layout,
- ID *fcurve_owner_id,
- FModifier *fcm,
- short UNUSED(width))
+static void panel_register_cycles(ARegionType *region_type,
+ const char *id_prefix,
+ PanelTypePollFn poll_fn)
{
- uiLayout *split, *col;
- PointerRNA ptr;
-
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierCycles, fcm, &ptr);
-
- /* split into 2 columns
- * NOTE: the mode combination-boxes shouldn't get labels, otherwise there isn't enough room. */
- split = uiLayoutSplit(layout, 0.5f, false);
-
- /* before range */
- col = uiLayoutColumn(split, true);
- uiItemL(col, IFACE_("Before:"), ICON_NONE);
- uiItemR(col, &ptr, "mode_before", 0, "", ICON_NONE);
- uiItemR(col, &ptr, "cycles_before", 0, NULL, ICON_NONE);
-
- /* after range */
- col = uiLayoutColumn(split, true);
- uiItemL(col, IFACE_("After:"), ICON_NONE);
- uiItemR(col, &ptr, "mode_after", 0, "", ICON_NONE);
- uiItemR(col, &ptr, "cycles_after", 0, NULL, ICON_NONE);
+ PanelType *panel_type = fmodifier_panel_register(
+ region_type, FMODIFIER_TYPE_CYCLES, cycles_panel_draw, poll_fn, id_prefix);
+ fmodifier_subpanel_register(region_type,
+ "frame_range",
+ "",
+ fmodifier_frame_range_header_draw,
+ fmodifier_frame_range_draw,
+ poll_fn,
+ panel_type);
}
-/* --------------- */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Noise Modifier
+ * \{ */
-/* draw settings for noise modifier */
-static void draw_modifier__noise(uiLayout *layout,
- ID *fcurve_owner_id,
- FModifier *fcm,
- short UNUSED(width))
+static void noise_panel_draw(const bContext *C, Panel *panel)
{
- uiLayout *split, *col;
- PointerRNA ptr;
+ uiLayout *col;
+ uiLayout *layout = panel->layout;
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierNoise, fcm, &ptr);
+ PointerRNA *ptr = fmodifier_get_pointers(C, panel, NULL);
- /* blending mode */
- uiItemR(layout, &ptr, "blend_type", 0, NULL, ICON_NONE);
+ uiLayoutSetPropSep(layout, true);
+ uiLayoutSetPropDecorate(layout, false);
- /* split into 2 columns */
- split = uiLayoutSplit(layout, 0.5f, false);
+ uiItemR(layout, ptr, "blend_type", 0, NULL, ICON_NONE);
- /* col 1 */
- col = uiLayoutColumn(split, false);
- uiItemR(col, &ptr, "scale", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "strength", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "offset", 0, NULL, ICON_NONE);
+ col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "scale", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "strength", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "offset", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "phase", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "depth", 0, NULL, ICON_NONE);
- /* col 2 */
- col = uiLayoutColumn(split, false);
- uiItemR(col, &ptr, "phase", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "depth", 0, NULL, ICON_NONE);
+ fmodifier_influence_draw(layout, ptr);
+}
+
+static void panel_register_noise(ARegionType *region_type,
+ const char *id_prefix,
+ PanelTypePollFn poll_fn)
+{
+ PanelType *panel_type = fmodifier_panel_register(
+ region_type, FMODIFIER_TYPE_NOISE, noise_panel_draw, poll_fn, id_prefix);
+ fmodifier_subpanel_register(region_type,
+ "frame_range",
+ "",
+ fmodifier_frame_range_header_draw,
+ fmodifier_frame_range_draw,
+ poll_fn,
+ panel_type);
}
-/* callback to add new envelope data point */
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name Enevelope Modifier
+ * \{ */
+
static void fmod_envelope_addpoint_cb(bContext *C, void *fcm_dv, void *UNUSED(arg))
{
Scene *scene = CTX_data_scene(C);
@@ -656,132 +687,60 @@ static void fmod_envelope_deletepoint_cb(bContext *UNUSED(C), void *fcm_dv, void
}
/* draw settings for envelope modifier */
-static void draw_modifier__envelope(uiLayout *layout,
- ID *fcurve_owner_id,
- FModifier *fcm,
- short UNUSED(width))
+static void envelope_panel_draw(const bContext *C, Panel *panel)
{
+ uiLayout *row, *col;
+ uiLayout *layout = panel->layout;
+
+ ID *owner_id;
+ PointerRNA *ptr = fmodifier_get_pointers(C, panel, &owner_id);
+ FModifier *fcm = (FModifier *)ptr->data;
FMod_Envelope *env = (FMod_Envelope *)fcm->data;
- FCM_EnvelopeData *fed;
- uiLayout *col, *row;
- uiBlock *block;
- uiBut *but;
- PointerRNA ptr;
- int i;
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierEnvelope, fcm, &ptr);
+ uiLayoutSetPropSep(layout, true);
- /* general settings */
+ /* General settings. */
col = uiLayoutColumn(layout, true);
- uiItemL(col, IFACE_("Envelope:"), ICON_NONE);
- uiItemR(col, &ptr, "reference_value", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "reference_value", 0, IFACE_("Reference"), ICON_NONE);
+ uiItemR(col, ptr, "default_min", 0, IFACE_("Min"), ICON_NONE);
+ uiItemR(col, ptr, "default_max", 0, IFACE_("Max"), ICON_NONE);
- row = uiLayoutRow(col, true);
- uiItemR(row, &ptr, "default_min", 0, IFACE_("Min"), ICON_NONE);
- uiItemR(row, &ptr, "default_max", 0, IFACE_("Max"), ICON_NONE);
+ /* Control points list. */
- /* control points header */
- /* TODO: move this control-point control stuff to using the new special widgets for lists
- * the current way is far too cramped */
row = uiLayoutRow(layout, false);
- block = uiLayoutGetBlock(row);
-
- uiDefBut(block,
- UI_BTYPE_LABEL,
- 1,
- IFACE_("Control Points:"),
- 0,
- 0,
- 7.5 * UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0,
- 0,
- "");
-
- but = uiDefBut(block,
- UI_BTYPE_BUT,
- B_FMODIFIER_REDRAW,
- IFACE_("Add Point"),
- 0,
- 0,
- 7.5 * UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0,
- 0,
- 0,
- 0,
- TIP_("Add a new control-point to the envelope on the current frame"));
+ uiBlock *block = uiLayoutGetBlock(row);
+
+ uiBut *but = uiDefBut(block,
+ UI_BTYPE_BUT,
+ B_FMODIFIER_REDRAW,
+ IFACE_("Add Control Point"),
+ 0,
+ 0,
+ 7.5 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0,
+ 0,
+ 0,
+ 0,
+ TIP_("Add a new control-point to the envelope on the current frame"));
UI_but_func_set(but, fmod_envelope_addpoint_cb, env, NULL);
- /* control points list */
- for (i = 0, fed = env->data; i < env->totvert; i++, fed++) {
+ col = uiLayoutColumn(layout, false);
+ uiLayoutSetPropSep(col, false);
+
+ FCM_EnvelopeData *fed = env->data;
+ for (int i = 0; i < env->totvert; i++, fed++) {
PointerRNA ctrl_ptr;
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierEnvelopeControlPoint, fed, &ctrl_ptr);
+ RNA_pointer_create(owner_id, &RNA_FModifierEnvelopeControlPoint, fed, &ctrl_ptr);
/* get a new row to operate on */
- row = uiLayoutRow(layout, true);
+ row = uiLayoutRow(col, true);
block = uiLayoutGetBlock(row);
- UI_block_align_begin(block);
- but = uiDefButR(block,
- UI_BTYPE_NUM,
- B_FMODIFIER_REDRAW,
- IFACE_("Fra:"),
- 0,
- 0,
- 4.5 * UI_UNIT_X,
- UI_UNIT_Y,
- &ctrl_ptr,
- "frame",
- -1,
- -MAXFRAMEF,
- MAXFRAMEF,
- 0,
- 0,
- NULL);
- UI_but_number_step_size_set(but, 10);
- UI_but_number_precision_set(but, 1);
- but = uiDefButR(block,
- UI_BTYPE_NUM,
- B_FMODIFIER_REDRAW,
- IFACE_("Min:"),
- 0,
- 0,
- 5 * UI_UNIT_X,
- UI_UNIT_Y,
- &ctrl_ptr,
- "min",
- -1,
- -UI_FLT_MAX,
- UI_FLT_MAX,
- 0,
- 0,
- NULL);
- UI_but_number_step_size_set(but, 10);
- UI_but_number_precision_set(but, 2);
- but = uiDefButR(block,
- UI_BTYPE_NUM,
- B_FMODIFIER_REDRAW,
- IFACE_("Max:"),
- 0,
- 0,
- 5 * UI_UNIT_X,
- UI_UNIT_Y,
- &ctrl_ptr,
- "max",
- -1,
- -UI_FLT_MAX,
- UI_FLT_MAX,
- 0,
- 0,
- NULL);
- UI_but_number_step_size_set(but, 10);
- UI_but_number_precision_set(but, 2);
+ uiItemR(row, &ctrl_ptr, "frame", 0, NULL, ICON_NONE);
+ uiItemR(row, &ctrl_ptr, "min", 0, IFACE_("Min"), ICON_NONE);
+ uiItemR(row, &ctrl_ptr, "max", 0, IFACE_("Max"), ICON_NONE);
but = uiDefIconBut(block,
UI_BTYPE_BUT,
@@ -800,251 +759,211 @@ static void draw_modifier__envelope(uiLayout *layout,
UI_but_func_set(but, fmod_envelope_deletepoint_cb, env, POINTER_FROM_INT(i));
UI_block_align_begin(block);
}
-}
-/* --------------- */
+ fmodifier_influence_draw(layout, ptr);
+}
-/* draw settings for limits modifier */
-static void draw_modifier__limits(uiLayout *layout,
- ID *fcurve_owner_id,
- FModifier *fcm,
- short UNUSED(width))
+static void panel_register_envelope(ARegionType *region_type,
+ const char *id_prefix,
+ PanelTypePollFn poll_fn)
{
- uiLayout *split, *col /* , *row */ /* UNUSED */;
- PointerRNA ptr;
-
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierLimits, fcm, &ptr);
-
- /* row 1: minimum */
- {
- /* row = uiLayoutRow(layout, false); */ /* UNUSED */
-
- /* split into 2 columns */
- split = uiLayoutSplit(layout, 0.5f, false);
+ PanelType *panel_type = fmodifier_panel_register(
+ region_type, FMODIFIER_TYPE_ENVELOPE, envelope_panel_draw, poll_fn, id_prefix);
+ fmodifier_subpanel_register(region_type,
+ "frame_range",
+ "",
+ fmodifier_frame_range_header_draw,
+ fmodifier_frame_range_draw,
+ poll_fn,
+ panel_type);
+}
- /* x-minimum */
- col = uiLayoutColumn(split, true);
- uiItemR(col, &ptr, "use_min_x", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "min_x", 0, NULL, ICON_NONE);
+/** \} */
- /* y-minimum*/
- col = uiLayoutColumn(split, true);
- uiItemR(col, &ptr, "use_min_y", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "min_y", 0, NULL, ICON_NONE);
- }
+/* -------------------------------------------------------------------- */
+/** \name Limits Modifier
+ * \{ */
- /* row 2: maximum */
- {
- /* row = uiLayoutRow(layout, false); */ /* UNUSED */
+static void limits_panel_draw(const bContext *C, Panel *panel)
+{
+ uiLayout *col, *row, *sub;
+ uiLayout *layout = panel->layout;
- /* split into 2 columns */
- split = uiLayoutSplit(layout, 0.5f, false);
+ PointerRNA *ptr = fmodifier_get_pointers(C, panel, NULL);
- /* x-minimum */
- col = uiLayoutColumn(split, true);
- uiItemR(col, &ptr, "use_max_x", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "max_x", 0, NULL, ICON_NONE);
+ uiLayoutSetPropSep(layout, true);
- /* y-minimum*/
- col = uiLayoutColumn(split, true);
- uiItemR(col, &ptr, "use_max_y", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "max_y", 0, NULL, ICON_NONE);
- }
+ /* Minimums. */
+ col = uiLayoutColumn(layout, false);
+ row = uiLayoutRowWithHeading(col, true, IFACE_("Minumum X"));
+ uiItemR(row, ptr, "use_min_x", 0, "", ICON_NONE);
+ sub = uiLayoutColumn(row, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min_x"));
+ uiItemR(sub, ptr, "min_x", 0, "", ICON_NONE);
+
+ row = uiLayoutRowWithHeading(col, true, IFACE_("Y"));
+ uiItemR(row, ptr, "use_min_y", 0, "", ICON_NONE);
+ sub = uiLayoutColumn(row, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_min_y"));
+ uiItemR(sub, ptr, "min_y", 0, "", ICON_NONE);
+
+ /* Maximums. */
+ col = uiLayoutColumn(layout, false);
+ row = uiLayoutRowWithHeading(col, true, IFACE_("Maximum X"));
+ uiItemR(row, ptr, "use_max_x", 0, "", ICON_NONE);
+ sub = uiLayoutColumn(row, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max_x"));
+ uiItemR(sub, ptr, "max_x", 0, "", ICON_NONE);
+
+ row = uiLayoutRowWithHeading(col, true, IFACE_("Y"));
+ uiItemR(row, ptr, "use_max_y", 0, "", ICON_NONE);
+ sub = uiLayoutColumn(row, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_max_y"));
+ uiItemR(sub, ptr, "max_y", 0, "", ICON_NONE);
+
+ fmodifier_influence_draw(layout, ptr);
}
-/* --------------- */
-
-/* draw settings for stepped interpolation modifier */
-static void draw_modifier__stepped(uiLayout *layout,
- ID *fcurve_owner_id,
- FModifier *fcm,
- short UNUSED(width))
+static void panel_register_limits(ARegionType *region_type,
+ const char *id_prefix,
+ PanelTypePollFn poll_fn)
{
- uiLayout *col, *sub;
- PointerRNA ptr;
+ PanelType *panel_type = fmodifier_panel_register(
+ region_type, FMODIFIER_TYPE_LIMITS, limits_panel_draw, poll_fn, id_prefix);
+ fmodifier_subpanel_register(region_type,
+ "frame_range",
+ "",
+ fmodifier_frame_range_header_draw,
+ fmodifier_frame_range_draw,
+ poll_fn,
+ panel_type);
+}
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifierStepped, fcm, &ptr);
+/** \} */
- /* block 1: "stepping" settings */
- col = uiLayoutColumn(layout, false);
- uiItemR(col, &ptr, "frame_step", 0, NULL, ICON_NONE);
- uiItemR(col, &ptr, "frame_offset", 0, NULL, ICON_NONE);
+/* -------------------------------------------------------------------- */
+/** \name Stepped Interpolation Modifier
+ * \{ */
- /* block 2: start range settings */
- col = uiLayoutColumn(layout, true);
- uiItemR(col, &ptr, "use_frame_start", 0, NULL, ICON_NONE);
+static void stepped_panel_draw(const bContext *C, Panel *panel)
+{
+ uiLayout *col, *sub, *row;
+ uiLayout *layout = panel->layout;
- sub = uiLayoutColumn(col, true);
- uiLayoutSetActive(sub, RNA_boolean_get(&ptr, "use_frame_start"));
- uiItemR(sub, &ptr, "frame_start", 0, NULL, ICON_NONE);
+ PointerRNA *ptr = fmodifier_get_pointers(C, panel, NULL);
- /* block 3: end range settings */
- col = uiLayoutColumn(layout, true);
- uiItemR(col, &ptr, "use_frame_end", 0, NULL, ICON_NONE);
+ uiLayoutSetPropSep(layout, true);
- sub = uiLayoutColumn(col, true);
- uiLayoutSetActive(sub, RNA_boolean_get(&ptr, "use_frame_end"));
- uiItemR(sub, &ptr, "frame_end", 0, NULL, ICON_NONE);
+ /* Stepping Settings. */
+ col = uiLayoutColumn(layout, false);
+ uiItemR(col, ptr, "frame_step", 0, NULL, ICON_NONE);
+ uiItemR(col, ptr, "frame_offset", 0, NULL, ICON_NONE);
+
+ /* Start range settings. */
+ row = uiLayoutRowWithHeading(layout, true, IFACE_("Start Frame"));
+ uiItemR(row, ptr, "use_frame_start", 0, "", ICON_NONE);
+ sub = uiLayoutColumn(row, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_frame_start"));
+ uiItemR(sub, ptr, "frame_start", 0, "", ICON_NONE);
+
+ /* End range settings. */
+ row = uiLayoutRowWithHeading(layout, true, IFACE_("End Frame"));
+ uiItemR(row, ptr, "use_frame_end", 0, "", ICON_NONE);
+ sub = uiLayoutColumn(row, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(ptr, "use_frame_end"));
+ uiItemR(sub, ptr, "frame_end", 0, "", ICON_NONE);
+
+ fmodifier_influence_draw(layout, ptr);
}
-/* --------------- */
-
-void ANIM_uiTemplate_fmodifier_draw(uiLayout *layout,
- ID *fcurve_owner_id,
- ListBase *modifiers,
- FModifier *fcm)
+static void panel_register_stepped(ARegionType *region_type,
+ const char *id_prefix,
+ PanelTypePollFn poll_fn)
{
- const FModifierTypeInfo *fmi = fmodifier_get_typeinfo(fcm);
- uiLayout *box, *row, *sub, *col;
- uiBlock *block;
- uiBut *but;
- short width = 314;
- PointerRNA ptr;
-
- /* init the RNA-pointer */
- RNA_pointer_create(fcurve_owner_id, &RNA_FModifier, fcm, &ptr);
+ PanelType *panel_type = fmodifier_panel_register(
+ region_type, FMODIFIER_TYPE_STEPPED, stepped_panel_draw, poll_fn, id_prefix);
+ fmodifier_subpanel_register(region_type,
+ "frame_range",
+ "",
+ fmodifier_frame_range_header_draw,
+ fmodifier_frame_range_draw,
+ poll_fn,
+ panel_type);
+}
- /* draw header */
- {
- /* get layout-row + UI-block for this */
- box = uiLayoutBox(layout);
+/** \} */
- row = uiLayoutRow(box, false);
- block = uiLayoutGetBlock(row); /* err... */
+/* -------------------------------------------------------------------- */
+/** \name Panel Creation
+ *
+ * \{ */
- /* left-align -------------------------------------------- */
- sub = uiLayoutRow(row, true);
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
+/**
+ * Checks if the panels match the active strip / curve, rebubilds them if they don't.
+ */
+void ANIM_fmodifier_panels(const bContext *C,
+ ID *owner_id,
+ ListBase *fmodifiers,
+ uiListPanelIDFromDataFunc panel_id_fn)
+{
+ ARegion *region = CTX_wm_region(C);
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
+ bool panels_match = UI_panel_list_matches_data(region, fmodifiers, panel_id_fn);
- /* expand */
- uiItemR(sub, &ptr, "show_expanded", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ if (!panels_match) {
+ UI_panels_free_instanced(C, region);
+ FModifier *fcm = fmodifiers->first;
+ for (int i = 0; fcm; i++, fcm = fcm->next) {
+ char panel_idname[MAX_NAME];
+ panel_id_fn(fcm, panel_idname);
- /* checkbox for 'active' status (for now) */
- uiItemR(sub, &ptr, "active", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+ PointerRNA *fcm_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
+ RNA_pointer_create(owner_id, &RNA_FModifier, fcm, fcm_ptr);
- /* name */
- if (fmi) {
- uiItemL(sub, IFACE_(fmi->name), ICON_NONE);
- }
- else {
- uiItemL(sub, IFACE_("<Unknown Modifier>"), ICON_NONE);
+ UI_panel_add_instanced(C, region, &region->panels, panel_idname, fcm_ptr);
}
-
- /* right-align ------------------------------------------- */
- sub = uiLayoutRow(row, true);
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_RIGHT);
-
- /* 'mute' button */
- uiItemR(sub, &ptr, "mute", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
-
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
- /* delete button */
- but = uiDefIconBut(block,
- UI_BTYPE_BUT,
- B_REDR,
- ICON_X,
- 0,
- 0,
- UI_UNIT_X,
- UI_UNIT_Y,
- NULL,
- 0.0,
- 0.0,
- 0.0,
- 0.0,
- TIP_("Delete F-Curve Modifier"));
- FModifierDeleteContext *ctx = MEM_mallocN(sizeof(FModifierDeleteContext), "fmodifier ctx");
- ctx->fcurve_owner_id = fcurve_owner_id;
- ctx->modifiers = modifiers;
- UI_but_funcN_set(but, delete_fmodifier_cb, ctx, fcm);
-
- UI_block_emboss_set(block, UI_EMBOSS);
}
-
- /* when modifier is expanded, draw settings */
- if (fcm->flag & FMODIFIER_FLAG_EXPANDED) {
- /* set up the flexible-box layout which acts as the backdrop for the modifier settings */
- box = uiLayoutBox(layout);
-
- /* draw settings for individual modifiers */
- switch (fcm->type) {
- case FMODIFIER_TYPE_GENERATOR: /* Generator */
- draw_modifier__generator(box, fcurve_owner_id, fcm, width);
- break;
-
- case FMODIFIER_TYPE_FN_GENERATOR: /* Built-In Function Generator */
- draw_modifier__fn_generator(box, fcurve_owner_id, fcm, width);
- break;
-
- case FMODIFIER_TYPE_CYCLES: /* Cycles */
- draw_modifier__cycles(box, fcurve_owner_id, fcm, width);
- break;
-
- case FMODIFIER_TYPE_ENVELOPE: /* Envelope */
- draw_modifier__envelope(box, fcurve_owner_id, fcm, width);
- break;
-
- case FMODIFIER_TYPE_LIMITS: /* Limits */
- draw_modifier__limits(box, fcurve_owner_id, fcm, width);
- break;
-
- case FMODIFIER_TYPE_NOISE: /* Noise */
- draw_modifier__noise(box, fcurve_owner_id, fcm, width);
- break;
-
- case FMODIFIER_TYPE_STEPPED: /* Stepped */
- draw_modifier__stepped(box, fcurve_owner_id, fcm, width);
- break;
-
- default: /* unknown type */
- break;
- }
-
- /* one last panel below this: FModifier range */
- /* TODO: experiment with placement of this */
- {
- box = uiLayoutBox(layout);
-
- /* restricted range ----------------------------------------------------- */
- col = uiLayoutColumn(box, true);
-
- /* top row: use restricted range */
- row = uiLayoutRow(col, true);
- uiItemR(row, &ptr, "use_restricted_range", 0, NULL, ICON_NONE);
-
- if (fcm->flag & FMODIFIER_FLAG_RANGERESTRICT) {
- /* second row: settings */
- row = uiLayoutRow(col, true);
-
- uiItemR(row, &ptr, "frame_start", 0, IFACE_("Start"), ICON_NONE);
- uiItemR(row, &ptr, "frame_end", 0, IFACE_("End"), ICON_NONE);
-
- /* third row: blending influence */
- row = uiLayoutRow(col, true);
-
- uiItemR(row, &ptr, "blend_in", 0, IFACE_("In"), ICON_NONE);
- uiItemR(row, &ptr, "blend_out", 0, IFACE_("Out"), ICON_NONE);
+ else {
+ /* Assuming there's only one group of instanced panels, update the custom data pointers. */
+ Panel *panel = region->panels.first;
+ LISTBASE_FOREACH (FModifier *, fcm, fmodifiers) {
+
+ /* Move to the next instanced panel corresponding to the next modifier. */
+ while ((panel->type == NULL) || !(panel->type->flag & PANEL_TYPE_INSTANCED)) {
+ panel = panel->next;
+ BLI_assert(panel != NULL); /* There shouldn't be fewer panels than modifiers with UIs. */
}
- /* influence -------------------------------------------------------------- */
- col = uiLayoutColumn(box, true);
-
- /* top row: use influence */
- uiItemR(col, &ptr, "use_influence", 0, NULL, ICON_NONE);
+ PointerRNA *fcm_ptr = MEM_mallocN(sizeof(PointerRNA), "panel customdata");
+ RNA_pointer_create(owner_id, &RNA_FModifier, fcm, fcm_ptr);
+ UI_panel_custom_data_set(panel, fcm_ptr);
- if (fcm->flag & FMODIFIER_FLAG_USEINFLUENCE) {
- /* second row: influence value */
- uiItemR(col, &ptr, "influence", 0, NULL, ICON_NONE);
- }
+ panel = panel->next;
}
}
}
+void ANIM_modifier_panels_register_graph_and_NLA(ARegionType *region_type,
+ const char *modifier_panel_prefix,
+ PanelTypePollFn poll_function)
+{
+ panel_register_generator(region_type, modifier_panel_prefix, poll_function);
+ panel_register_fn_generator(region_type, modifier_panel_prefix, poll_function);
+ panel_register_noise(region_type, modifier_panel_prefix, poll_function);
+ panel_register_envelope(region_type, modifier_panel_prefix, poll_function);
+ panel_register_limits(region_type, modifier_panel_prefix, poll_function);
+ panel_register_stepped(region_type, modifier_panel_prefix, poll_function);
+}
+
+void ANIM_modifier_panels_register_graph_only(ARegionType *region_type,
+ const char *modifier_panel_prefix,
+ PanelTypePollFn poll_function)
+{
+ panel_register_cycles(region_type, modifier_panel_prefix, poll_function);
+}
+
+/** \} */
+
/* -------------------------------------------------------------------- */
/** \name Copy / Paste Buffer Code
*
diff --git a/source/blender/editors/include/ED_anim_api.h b/source/blender/editors/include/ED_anim_api.h
index 9cf67816df2..2415c85e299 100644
--- a/source/blender/editors/include/ED_anim_api.h
+++ b/source/blender/editors/include/ED_anim_api.h
@@ -33,7 +33,11 @@ struct ID;
struct ListBase;
struct ARegion;
+struct ARegionType;
struct Main;
+struct NlaStrip;
+struct FModifier;
+struct PanelType;
struct ReportList;
struct ScrArea;
struct SpaceLink;
@@ -675,11 +679,25 @@ void ANIM_draw_framerange(struct Scene *scene, struct View2D *v2d);
/* ------------- UI Panel Drawing -------------- */
-/* draw a given F-Modifier for some layout/UI-Block */
-void ANIM_uiTemplate_fmodifier_draw(struct uiLayout *layout,
- struct ID *fcurve_owner_id,
- ListBase *modifiers,
- struct FModifier *fcm);
+struct NlaStrip *ANIM_nla_context_strip(const struct bContext *C);
+struct FCurve *ANIM_graph_context_fcurve(const struct bContext *C);
+
+/* Needed for abstraction between the graph editor and the NLA editor. */
+typedef bool (*PanelTypePollFn)(const struct bContext *C, struct PanelType *pt);
+/* Avoid including "UI_interface.h" here. */
+typedef void (*uiListPanelIDFromDataFunc)(void *data_link, char *r_idname);
+
+void ANIM_fmodifier_panels(const struct bContext *C,
+ struct ID *owner_id,
+ struct ListBase *fmodifiers,
+ uiListPanelIDFromDataFunc panel_id_fn);
+
+void ANIM_modifier_panels_register_graph_and_NLA(struct ARegionType *region_type,
+ const char *modifier_panel_prefix,
+ PanelTypePollFn poll_function);
+void ANIM_modifier_panels_register_graph_only(struct ARegionType *region_type,
+ const char *modifier_panel_prefix,
+ PanelTypePollFn poll_function);
/* ------------- Copy/Paste Buffer -------------- */
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index 51be5afafe5..d88bf8750c2 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -105,6 +105,16 @@ static bool graph_panel_context(const bContext *C, bAnimListElem **ale, FCurve *
return true;
}
+FCurve *ANIM_graph_context_fcurve(const bContext *C)
+{
+ FCurve *fcu;
+ if (!graph_panel_context(C, NULL, &fcu)) {
+ return NULL;
+ }
+
+ return fcu;
+}
+
static bool graph_panel_poll(const bContext *C, PanelType *UNUSED(pt))
{
return graph_panel_context(C, NULL, NULL);
@@ -1312,6 +1322,16 @@ static void graph_panel_drivers_popover(const bContext *C, Panel *panel)
/* All the drawing code is in editors/animation/fmodifier_ui.c */
#define B_FMODIFIER_REDRAW 20
+/** The start of FModifier panels registered for the graph editor. */
+#define GRAPH_FMODIFIER_PANEL_PREFIX "GRAPH"
+
+static void graph_fmodifier_panel_id(void *fcm_link, char *r_name)
+{
+ FModifier *fcm = (FModifier *)fcm_link;
+ eFModifier_Types type = fcm->type;
+ const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(type);
+ BLI_snprintf(r_name, BKE_ST_MAXNAME, "%s_PT_%s", GRAPH_FMODIFIER_PANEL_PREFIX, fmi->name);
+}
static void do_graph_region_modifier_buttons(bContext *C, void *UNUSED(arg), int event)
{
@@ -1327,10 +1347,8 @@ static void graph_panel_modifiers(const bContext *C, Panel *panel)
{
bAnimListElem *ale;
FCurve *fcu;
- FModifier *fcm;
- uiLayout *col, *row;
+ uiLayout *row;
uiBlock *block;
- bool active;
if (!graph_panel_context(C, &ale, &fcu)) {
return;
@@ -1355,14 +1373,7 @@ static void graph_panel_modifiers(const bContext *C, Panel *panel)
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(panel->layout, true);
- uiLayoutSetActive(col, active);
-
- ANIM_uiTemplate_fmodifier_draw(col, ale->fcurve_owner_id, &fcu->modifiers, fcm);
- }
+ ANIM_fmodifier_panels(C, ale->fcurve_owner_id, &fcu->modifiers, graph_fmodifier_panel_id);
MEM_freeN(ale);
}
@@ -1426,10 +1437,14 @@ void graph_buttons_register(ARegionType *art)
strcpy(pt->label, N_("Modifiers"));
strcpy(pt->category, "Modifiers");
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->flag = PANEL_TYPE_NO_HEADER;
pt->draw = graph_panel_modifiers;
pt->poll = graph_panel_poll;
BLI_addtail(&art->paneltypes, pt);
+ ANIM_modifier_panels_register_graph_and_NLA(art, GRAPH_FMODIFIER_PANEL_PREFIX, graph_panel_poll);
+ ANIM_modifier_panels_register_graph_only(art, GRAPH_FMODIFIER_PANEL_PREFIX, graph_panel_poll);
+
pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel view");
strcpy(pt->idname, "GRAPH_PT_view");
strcpy(pt->label, N_("Show Cursor"));
diff --git a/source/blender/editors/space_nla/nla_buttons.c b/source/blender/editors/space_nla/nla_buttons.c
index b82fcf3db47..d019573bf93 100644
--- a/source/blender/editors/space_nla/nla_buttons.c
+++ b/source/blender/editors/space_nla/nla_buttons.c
@@ -37,6 +37,7 @@
#include "BLT_translation.h"
#include "BKE_context.h"
+#include "BKE_fcurve.h"
#include "BKE_nla.h"
#include "BKE_screen.h"
@@ -184,6 +185,17 @@ bool nla_panel_context(const bContext *C,
return (found != 0);
}
+NlaStrip *ANIM_nla_context_strip(const bContext *C)
+{
+ PointerRNA strip_ptr;
+ if (!nla_panel_context(C, NULL, NULL, &strip_ptr)) {
+ return NULL;
+ }
+ NlaStrip *strip = strip_ptr.data;
+
+ return strip;
+}
+
#if 0
static bool nla_panel_poll(const bContext *C, PanelType *pt)
{
@@ -535,13 +547,23 @@ static void nla_panel_animated_strip_time(const bContext *C, Panel *panel)
uiItemR(layout, &strip_ptr, "strip_time", 0, NULL, ICON_NONE);
}
+#define NLA_FMODIFIER_PANEL_PREFIX "NLA"
+
+static void nla_fmodifier_panel_id(void *fcm_link, char *r_name)
+{
+ FModifier *fcm = (FModifier *)fcm_link;
+ eFModifier_Types type = fcm->type;
+ snprintf(r_name, BKE_ST_MAXNAME, "%s_PT_", NLA_FMODIFIER_PANEL_PREFIX);
+ const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(type);
+ BLI_snprintf(r_name, BKE_ST_MAXNAME, "%s_PT_%s", NLA_FMODIFIER_PANEL_PREFIX, fmi->name);
+}
+
/* F-Modifiers for active NLA-Strip */
static void nla_panel_modifiers(const bContext *C, Panel *panel)
{
PointerRNA strip_ptr;
NlaStrip *strip;
- FModifier *fcm;
- uiLayout *col, *row;
+ uiLayout *row;
uiBlock *block;
/* check context and also validity of pointer */
@@ -569,12 +591,7 @@ static void nla_panel_modifiers(const bContext *C, Panel *panel)
uiItemO(row, "", ICON_PASTEDOWN, "NLA_OT_fmodifier_paste");
}
- /* draw each modifier */
- for (fcm = strip->modifiers.first; fcm; fcm = fcm->next) {
- col = uiLayoutColumn(panel->layout, true);
-
- ANIM_uiTemplate_fmodifier_draw(col, strip_ptr.owner_id, &strip->modifiers, fcm);
- }
+ ANIM_fmodifier_panels(C, strip_ptr.owner_id, &strip->modifiers, nla_fmodifier_panel_id);
}
/* ******************* general ******************************** */
@@ -657,5 +674,9 @@ void nla_buttons_register(ARegionType *art)
strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
pt->draw = nla_panel_modifiers;
pt->poll = nla_strip_eval_panel_poll;
+ pt->flag = PANEL_TYPE_NO_HEADER;
BLI_addtail(&art->paneltypes, pt);
+
+ ANIM_modifier_panels_register_graph_and_NLA(
+ art, NLA_FMODIFIER_PANEL_PREFIX, nla_strip_eval_panel_poll);
}
diff --git a/source/blender/makesdna/DNA_anim_types.h b/source/blender/makesdna/DNA_anim_types.h
index 4e37a6652a5..c9abb4fb5be 100644
--- a/source/blender/makesdna/DNA_anim_types.h
+++ b/source/blender/makesdna/DNA_anim_types.h
@@ -57,6 +57,13 @@ typedef struct FModifier {
short type;
/** Settings for the modifier. */
short flag;
+ /**
+ * Expansion state for the modifier panel and its subpanels, stored as a bitfield
+ * in depth-first order. (Maximum of sizeof(short) total panels).
+ */
+ short ui_expand_flag;
+
+ char _pad[6];
/** The amount that the modifier should influence the value. */
float influence;
@@ -96,8 +103,10 @@ typedef enum eFModifier_Types {
typedef enum eFModifier_Flags {
/** Modifier is not able to be evaluated for some reason, and should be skipped (internal). */
FMODIFIER_FLAG_DISABLED = (1 << 0),
- /** Modifier's data is expanded (in UI). */
+#ifdef DNA_DEPRECATED_ALLOW
+ /** Modifier's data is expanded (in UI). Deprecated, use `ui_expand_flag`. */
FMODIFIER_FLAG_EXPANDED = (1 << 1),
+#endif
/** Modifier is active one (in UI) for editing purposes. */
FMODIFIER_FLAG_ACTIVE = (1 << 2),
/** User wants modifier to be skipped. */
diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c
index b4e864eb4e1..989a41b9ad6 100644
--- a/source/blender/makesrna/intern/rna_fcurve.c
+++ b/source/blender/makesrna/intern/rna_fcurve.c
@@ -1129,6 +1129,12 @@ static void rna_Keyframe_update(Main *bmain, Scene *UNUSED(scene), PointerRNA *p
rna_tag_animation_update(bmain, ptr->owner_id);
}
+static void rna_FModifier_show_expanded_set(PointerRNA *ptr, bool value)
+{
+ FModifier *fcm = ptr->data;
+ SET_FLAG_FROM_TEST(fcm->ui_expand_flag, value, UI_PANEL_DATA_EXPAND_ROOT);
+}
+
#else
static void rna_def_fmodifier_generator(BlenderRNA *brna)
@@ -1187,6 +1193,8 @@ static void rna_def_fmodifier_generator(BlenderRNA *brna)
NULL);
RNA_def_property_ui_text(
prop, "Coefficients", "Coefficients for 'x' (starting from lowest power of x^0)");
+ RNA_def_property_update(
+ prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_verify_data_update");
}
/* --------- */
@@ -1219,7 +1227,7 @@ static void rna_def_fmodifier_function_generator(BlenderRNA *brna)
prop = RNA_def_property(srna, "phase_multiplier", PROP_FLOAT, PROP_NONE);
RNA_def_property_ui_text(
- prop, "Phase Multiplier", "Scale factor determining the 'speed' of the function");
+ prop, "Phase Multiple", "Scale factor determining the 'speed' of the function");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, "rna_FModifier_update");
prop = RNA_def_property(srna, "phase_offset", PROP_FLOAT, PROP_NONE);
@@ -1632,13 +1640,14 @@ static void rna_def_fmodifier(BlenderRNA *brna)
/* settings */
prop = RNA_def_property(srna, "show_expanded", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_flag(prop, PROP_NO_DEG_UPDATE);
- RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_EXPANDED);
+ RNA_def_property_boolean_sdna(prop, NULL, "ui_expand_flag", 0);
+ RNA_def_property_boolean_funcs(prop, NULL, "rna_FModifier_show_expanded_set");
RNA_def_property_ui_text(prop, "Expanded", "F-Curve Modifier's panel is expanded in UI");
RNA_def_property_ui_icon(prop, ICON_DISCLOSURE_TRI_RIGHT, 1);
prop = RNA_def_property(srna, "mute", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_MUTED);
- RNA_def_property_ui_text(prop, "Muted", "Disable F-Curve Modifier evaluation");
+ RNA_def_property_ui_text(prop, "Enabled", "Enable F-Curve modifier evaluation");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_update");
RNA_def_property_ui_icon(prop, ICON_CHECKBOX_HLT, -1);
@@ -1652,7 +1661,7 @@ static void rna_def_fmodifier(BlenderRNA *brna)
/* TODO: setting this to true must ensure that all others in stack are turned off too... */
prop = RNA_def_property(srna, "active", PROP_BOOLEAN, PROP_NONE);
RNA_def_property_boolean_sdna(prop, NULL, "flag", FMODIFIER_FLAG_ACTIVE);
- RNA_def_property_ui_text(prop, "Active", "F-Curve Modifier is the one being edited");
+ RNA_def_property_ui_text(prop, "Active", "F-Curve modifier will show settings in the editor");
RNA_def_property_boolean_funcs(prop, NULL, "rna_FModifier_active_set");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_active_update");
RNA_def_property_ui_icon(prop, ICON_RADIOBUT_OFF, 1);
@@ -1666,8 +1675,6 @@ static void rna_def_fmodifier(BlenderRNA *brna)
"F-Curve Modifier is only applied for the specified frame range to help "
"mask off effects in order to chain them");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_update");
- RNA_def_property_ui_icon(
- prop, ICON_DISCLOSURE_TRI_RIGHT, 1); /* XXX: depends on UI implementation */
prop = RNA_def_property(srna, "frame_start", PROP_FLOAT, PROP_NONE);
RNA_def_property_float_sdna(prop, NULL, "sfra");
@@ -1709,8 +1716,6 @@ static void rna_def_fmodifier(BlenderRNA *brna)
RNA_def_property_ui_text(
prop, "Use Influence", "F-Curve Modifier's effects will be tempered by a default factor");
RNA_def_property_update(prop, NC_ANIMATION | ND_KEYFRAME_PROP, "rna_FModifier_update");
- RNA_def_property_ui_icon(
- prop, ICON_DISCLOSURE_TRI_RIGHT, 1); /* XXX: depends on UI implementation */
prop = RNA_def_property(srna, "influence", PROP_FLOAT, PROP_FACTOR);
RNA_def_property_float_sdna(prop, NULL, "influence");