[Bf-blender-cvs] [fea5097eb83] fcurve-modifier-panels: UI: Drag and Drop FModifiers, Layout Updates
Hans Goudey
noreply at git.blender.org
Mon Oct 19 04:44:59 CEST 2020
Commit: fea5097eb83593b612fd2f1dab662350d716025a
Author: Hans Goudey
Date: Thu Jun 11 11:13:54 2020 -0400
Branches: fcurve-modifier-panels
https://developer.blender.org/rBfea5097eb83593b612fd2f1dab662350d716025a
UI: Drag and Drop FModifiers, Layout Updates
There are still problems
- Context doesn't work in NLA editor
- Lots of memory leaks for anim context.
Should find a different method for getting the context that doesn't require a "free" every time.
This also adds support for regions with panel categories to the list panel system, which was a simple oversight.
Differential Revision: https://developer.blender.org/D7997
===================================================================
M source/blender/blenkernel/BKE_fcurve.h
M source/blender/blenkernel/intern/fmodifier.c
M source/blender/editors/animation/fmodifier_ui.c
M source/blender/editors/include/ED_anim_api.h
M source/blender/editors/space_graph/graph_buttons.c
M source/blender/editors/space_nla/nla_buttons.c
M source/blender/makesdna/DNA_anim_types.h
M source/blender/makesrna/intern/rna_fcurve.c
===================================================================
diff --git a/source/blender/blenkernel/BKE_fcurve.h b/source/blender/blenkernel/BKE_fcurve.h
index c3a597e29b9..bb31014308e 100644
--- a/source/blender/blenkernel/BKE_fcurve.h
+++ b/source/blender/blenkernel/BKE_fcurve.h
@@ -36,6 +36,7 @@ struct FCurve;
struct FModifier;
struct AnimData;
+struct ARegionType;
struct BezTriple;
struct LibraryForeachIDData;
struct PathResolvedRNA;
diff --git a/source/blender/blenkernel/intern/fmodifier.c b/source/blender/blenkernel/intern/fmodifier.c
index c85283e3653..1c0a1399479 100644
--- a/source/blender/blenkernel/intern/fmodifier.c
+++ b/source/blender/blenkernel/intern/fmodifier.c
@@ -375,7 +375,7 @@ static FModifierTypeInfo FMI_FN_GENERATOR = {
sizeof(FMod_FunctionGenerator), /* size */
FMI_TYPE_GENERATE_CURVE, /* action type */
FMI_REQUIRES_NOTHING, /* requirements */
- N_("Built-In Function"), /* name */
+ N_("Function"), /* name */
"FMod_FunctionGenerator", /* struct name */
0, /* storage size */
NULL, /* free data */
@@ -1123,7 +1123,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 = 1;
fcm->curve = owner_fcu;
fcm->influence = 1.0f;
BLI_addtail(modifiers, fcm);
diff --git a/source/blender/editors/animation/fmodifier_ui.c b/source/blender/editors/animation/fmodifier_ui.c
index eadaa449b92..d49e1306901 100644
--- a/source/blender/editors/animation/fmodifier_ui.c
+++ b/source/blender/editors/animation/fmodifier_ui.c
@@ -44,6 +44,7 @@
#include "BKE_context.h"
#include "BKE_fcurve.h"
+#include "BKE_screen.h"
#include "WM_api.h"
#include "WM_types.h"
@@ -58,8 +59,244 @@
#include "DEG_depsgraph.h"
-/* ********************************************** */
-/* UI STUFF */
+#include "anim_intern.h"
+
+typedef void (*PanelDrawFn)(const bContext *, struct Panel *);
+static void deg_update(bContext *C, void *owner_id, void *UNUSED(var2));
+static void fmodifier_panel_header(const bContext *C, Panel *panel);
+
+/* -------------------------------------------------------------------- */
+/** \name Panel Registering and Panel Callbacks
+ * \{ */
+
+static bAnimListElem *get_active_fcurve_channel(bAnimContext *ac)
+{
+ ListBase anim_data = {NULL, NULL};
+ int filter = (ANIMFILTER_DATA_VISIBLE | ANIMFILTER_FOREDIT | ANIMFILTER_ACTIVE);
+ size_t items = ANIM_animdata_filter(ac, &anim_data, filter, ac->data, ac->datatype);
+
+ /* We take the first F-Curve only, since some other ones may have had 'active' flag set
+ * if they were from linked data.
+ */
+ if (items) {
+ bAnimListElem *ale = (bAnimListElem *)anim_data.first;
+
+ /* remove first item from list, then free the rest of the list and return the stored one */
+ BLI_remlink(&anim_data, ale);
+ ANIM_animdata_freelist(&anim_data);
+
+ return ale;
+ }
+
+ /* no active F-Curve */
+ return NULL;
+}
+
+static int graph_panel_context(const bContext *C, bAnimListElem **ale, FCurve **fcu)
+{
+ bAnimContext ac;
+ bAnimListElem *elem = NULL;
+
+ /* For now, only draw if we could init the anim-context info
+ * (necessary for all animation-related tools)
+ * to work correctly is able to be correctly retrieved.
+ * There's no point showing empty panels?
+ */
+ if (ANIM_animdata_get_context(C, &ac) == 0) {
+ return 0;
+ }
+
+ /* try to find 'active' F-Curve */
+ elem = get_active_fcurve_channel(&ac);
+ if (elem == NULL) {
+ return 0;
+ }
+
+ if (fcu) {
+ *fcu = (FCurve *)elem->data;
+ }
+ if (ale) {
+ *ale = elem;
+ }
+ else {
+ MEM_freeN(elem);
+ }
+
+ return 1;
+}
+
+static void fmodifier_get_pointers(const bContext *C,
+ Panel *panel,
+ FModifier **r_fcm,
+ ID **r_owner_id)
+{
+ bAnimListElem *ale;
+ FCurve *fcu;
+ if (!graph_panel_context(C, &ale, &fcu)) {
+ return;
+ }
+ ListBase *modifiers = &fcu->modifiers;
+
+ *r_fcm = BLI_findlink(modifiers, panel->runtime.list_index);
+ *r_owner_id = ale->fcurve_owner_id;
+
+ uiLayoutSetActive(panel->layout, !(fcu->flag & FCURVE_MOD_OFF));
+}
+
+static bool graph_panel_poll(const bContext *C, PanelType *UNUSED(pt))
+{
+ return graph_panel_context(C, NULL, NULL);
+}
+
+/**
+ * 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)
+{
+ bAnimListElem *ale;
+ FCurve *fcu;
+ if (!graph_panel_context(C, &ale, &fcu)) {
+ return;
+ }
+
+ int current_index = panel->runtime.list_index;
+ if (current_index == new_index) {
+ return;
+ }
+
+ ListBase *modifiers = &fcu->modifiers;
+ FModifier *fcm = BLI_findlink(modifiers, current_index);
+ if (fcm == NULL) {
+ return;
+ }
+
+ /* Cycles modifier has to be the first, so make sure it's kept that way. */
+ if (fcm->type == FMODIFIER_TYPE_CYCLES) {
+ return;
+ }
+ FModifier *fcm_first = modifiers->first;
+ if (fcm_first->type == FMODIFIER_TYPE_CYCLES && new_index == 0) {
+ return;
+ }
+
+ BLI_assert(current_index >= 0);
+ BLI_assert(new_index >= 0);
+
+ /* Move the FModifier in the list. */
+ BLI_listbase_link_move(modifiers, fcm, new_index - current_index);
+
+ ED_undo_push(C, "Move F-Curve Modifier");
+
+ ID *fcurve_owner_id = ale->fcurve_owner_id;
+ WM_event_add_notifier(C, NC_ANIMATION | ND_KEYFRAME | NA_EDITED, NULL);
+ DEG_id_tag_update(fcurve_owner_id, ID_RECALC_ANIMATION);
+}
+
+#define FMODIFIER_TYPE_PANEL_PREFIX "ANIM_PT_"
+void ANIM_fmodifier_type_panel_id(int type, char *r_idname)
+{
+ const FModifierTypeInfo *fmi = get_fmodifier_typeinfo(type);
+
+ strcpy(r_idname, FMODIFIER_TYPE_PANEL_PREFIX);
+ strcat(r_idname, fmi->name);
+}
+
+static short get_fmodifier_expand_flag(const bContext *C, Panel *panel)
+{
+ FCurve *fcu;
+ if (!graph_panel_context(C, NULL, &fcu)) {
+ return 1;
+ }
+ FModifier *fcm = BLI_findlink(&fcu->modifiers, panel->runtime.list_index);
+ return fcm->ui_expand_flag;
+}
+
+static void set_fmodifier_expand_flag(const bContext *C, Panel *panel, short expand_flag)
+{
+ FCurve *fcu;
+ if (!graph_panel_context(C, NULL, &fcu)) {
+ return;
+ }
+ FModifier *fcm = BLI_findlink(&fcu->modifiers, panel->runtime.list_index);
+ fcm->ui_expand_flag = expand_flag;
+}
+
+static PanelType *fmodifier_panel_register(ARegionType *region_type,
+ eFModifier_Types type,
+ PanelDrawFn draw)
+{
+ /* Get the name for the modifier's panel. */
+ char panel_idname[BKE_ST_MAXNAME];
+ ANIM_fmodifier_type_panel_id(type, panel_idname);
+
+ PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
+
+ strcpy(panel_type->idname, panel_idname);
+ strcpy(panel_type->label, "");
+ strcpy(panel_type->category, "Modifiers");
+ strcpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+
+ panel_type->draw_header = fmodifier_panel_header;
+ panel_type->draw = draw;
+ panel_type->poll = graph_panel_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 = PNL_LAYOUT_HEADER_EXPAND | PNL_DRAW_BOX | PNL_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(®ion_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,
+ PanelType *parent)
+{
+ /* Create the subpanel's ID name. */
+ char panel_idname[BKE_ST_MAXNAME];
+ strcpy(panel_idname, parent->idname);
+ strcat(panel_idname, "_");
+ strcat(panel_idname, name);
+
+ PanelType *panel_type = MEM_callocN(sizeof(PanelType), panel_idname);
+
+ strcpy(panel_type->idname, panel_idname);
+ strcpy(panel_type->label, label);
+ strcpy(panel_type->category, "Modifiers");
+ strcpy(panel_type->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+
+ panel_type->draw_header = draw_header;
+ panel_type->draw = draw;
+ panel_type->poll = graph_panel_poll;
+ panel_type->flag = (PNL_DEFAULT_CLOSED | PNL_DRAW_BOX);
+
+ BLI_assert(parent != NULL);
+ strcpy(panel_type->parent_id, parent->idname);
+ panel_type->parent = parent;
+ BLI_addtail(&parent->children, BLI_genericNodeN(panel_type));
+ BLI_addtail(®ion_type->paneltypes, panel_type);
+
+ return panel_type;
+}
+
+/** \} */
+
+/* -------------------------------------------------------------------- */
+/** \name General UI Callbacks and Drawing
+ * \{ */
// XXX! --------------------------------
/* Temporary definition for limits of float number buttons
@@ -112,28 +349,156 @@ static void delete_fmodifier_cb(bContext *C, void *ctx_v, void *fcm_v)
deg_update(C, ctx->fcurve_owner_id, NULL);
}
-/* --------------- */
-/* 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, ID *fcurve_owner_id, FModifier *fcm)
{
- 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 */
+ RNA_pointer_create(fcurve_ow
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list