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. @@ _______________________________________________ Bf-blender-cvs mailing list [email protected] https://lists.blender.org/mailman/listinfo/bf-blender-cvs
