[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(&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,
+                                              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(&region_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