diff --git a/source/blender/editors/animation/anim_channels_defines.c b/source/blender/editors/animation/anim_channels_defines.c index c9052431d3c..7c9814eda7b 100644 --- a/source/blender/editors/animation/anim_channels_defines.c +++ b/source/blender/editors/animation/anim_channels_defines.c @@ -2189,7 +2189,7 @@ void ANIM_channel_draw (bAnimContext *ac, bAnimListElem *ale, float yminc, float /* ------------------ */ -/* callback for widget settings - send notifiers */ +/* callback for (normal) widget settings - send notifiers */ static void achannel_setting_widget_cb(bContext *C, void *poin, void *poin2) { WM_event_add_notifier(C, NC_ANIMATION|ND_ANIMCHAN_EDIT, NULL); diff --git a/source/blender/editors/interface/interface_templates.c b/source/blender/editors/interface/interface_templates.c index a7c586be42a..de0d6191f16 100644 --- a/source/blender/editors/interface/interface_templates.c +++ b/source/blender/editors/interface/interface_templates.c @@ -438,7 +438,6 @@ void uiTemplateAnyID(uiLayout *layout, bContext *C, PointerRNA *ptr, char *propn uiItemL(row, "ID-Block:", 0); /* ID-Type Selector - just have a menu of icons */ - // XXX should value really be 0? uiItemFullR(row, "", 0, ptr, propType, 0, 0, UI_ITEM_R_ICON_ONLY); /* ID-Block Selector - just use pointer widget... */ diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c index afc86309ffb..fa44b281f15 100644 --- a/source/blender/editors/space_graph/graph_buttons.c +++ b/source/blender/editors/space_graph/graph_buttons.c @@ -193,7 +193,7 @@ static void do_graph_region_driver_buttons(bContext *C, void *arg, int event) } /* default for now */ - WM_event_add_notifier(C, NC_SCENE, scene); + WM_event_add_notifier(C, NC_SCENE, scene); // XXX does this always work? } /* callback to remove the active driver */ @@ -251,21 +251,6 @@ static int graph_panel_drivers_poll(const bContext *C, PanelType *pt) return graph_panel_context(C, NULL, NULL); } -static void test_obpoin_but(struct bContext *C, char *name, ID **idpp) -{ - ID *id; - - id= CTX_data_main(C)->object.first; - while(id) { - if( strcmp(name, id->name+2)==0 ) { - *idpp= id; - id_lib_extern(id); /* checks lib data, sets correct flag for saving then */ - return; - } - id= id->next; - } - *idpp= NULL; -} /* driver settings for active F-Curve (only for 'Drivers' mode) */ static void graph_panel_drivers(const bContext *C, Panel *pa) @@ -275,91 +260,98 @@ static void graph_panel_drivers(const bContext *C, Panel *pa) ChannelDriver *driver; DriverTarget *dtar; - PointerRNA rna_ptr; + PointerRNA driver_ptr; + uiLayout *col; uiBlock *block; uiBut *but; - int yco=85, i=0; - - if(!graph_panel_context(C, &ale, &fcu)) + + /* Get settings from context */ + if (!graph_panel_context(C, &ale, &fcu)) return; - driver= fcu->driver; - block= uiLayoutAbsoluteBlock(pa->layout); + /* set event handler for panel */ + block= uiLayoutGetBlock(pa->layout); // xxx? uiBlockSetHandleFunc(block, do_graph_region_driver_buttons, NULL); - /* general actions */ - but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Update Dependencies", 10, 200, 180, 22, NULL, 0.0, 0.0, 0, 0, "Force updates of dependencies"); - uiButSetFunc(but, driver_update_flags_cb, fcu, NULL); - - but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Remove Driver", 200, 200, 110, 18, NULL, 0.0, 0.0, 0, 0, "Remove this driver"); - uiButSetFunc(but, driver_remove_cb, ale, NULL); - - /* type */ - uiDefBut(block, LABEL, 1, "Type:", 10, 170, 60, 20, NULL, 0.0, 0.0, 0, 0, ""); - uiDefButI(block, MENU, B_IPO_DEPCHANGE, - "Driver Type%t|Normal%x0|Scripted Expression%x1|Rotational Difference%x2", - 70,170,240,20, &driver->type, 0, 0, 0, 0, "Driver type"); - - /* show expression box if doing scripted drivers */ - if (driver->type == DRIVER_TYPE_PYTHON) { - uiDefBut(block, TEX, B_REDR, "Expr: ", 10,150,300,20, driver->expression, 0, 255, 0, 0, "One-liner Python Expression to use as Scripted Expression"); + /* general actions - management */ + col= uiLayoutColumn(pa->layout, 0); + block= uiLayoutGetBlock(col); + but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Update Dependencies", 0, 0, 10*UI_UNIT_X, 22, NULL, 0.0, 0.0, 0, 0, "Force updates of dependencies"); + uiButSetFunc(but, driver_update_flags_cb, fcu, NULL); - /* errors */ - if (driver->flag & DRIVER_FLAG_INVALID) { - uiDefIconBut(block, LABEL, 1, ICON_ERROR, 10, 130, 48, 48, NULL, 0, 0, 0, 0, ""); // a bit larger - uiDefBut(block, LABEL, 0, "Error: invalid Python expression", - 50,110,230,19, NULL, 0, 0, 0, 0, ""); - } - } - else { - /* errors */ - if (driver->flag & DRIVER_FLAG_INVALID) { - uiDefIconBut(block, LABEL, 1, ICON_ERROR, 10, 130, 48, 48, NULL, 0, 0, 0, 0, ""); // a bit larger - uiDefBut(block, LABEL, 0, "Error: invalid target channel(s)", - 50,130,230,19, NULL, 0, 0, 0, 0, ""); - } - } + but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Remove Driver", 0, 0, 10*UI_UNIT_X, 18, NULL, 0.0, 0.0, 0, 0, "Remove this driver"); + uiButSetFunc(but, driver_remove_cb, ale, NULL); + + /* driver-level settings - type, expressions, and errors */ + RNA_pointer_create(ale->id, &RNA_Driver, driver, &driver_ptr); - but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Add Variable", 10, 110, 300, 20, NULL, 0.0, 0.0, 0, 0, "Add a new target variable for this Driver"); - uiButSetFunc(but, driver_add_var_cb, driver, NULL); + col= uiLayoutColumn(pa->layout, 1); + block= uiLayoutGetBlock(col); + uiItemR(col, NULL, 0, &driver_ptr, "type", 0); + + /* show expression box if doing scripted drivers, and/or error messages when invalid drivers exist */ + if (driver->type == DRIVER_TYPE_PYTHON) { + /* expression */ + uiItemR(col, "Expr:", 0, &driver_ptr, "expression", 0); + + /* errors? */ + if (driver->flag & DRIVER_FLAG_INVALID) + uiItemL(col, "ERROR: invalid Python expression", ICON_ERROR); + } + else { + /* errors? */ + if (driver->flag & DRIVER_FLAG_INVALID) + uiItemL(col, "ERROR: invalid target channel(s)", ICON_ERROR); + } + + /* add driver target variables */ + col= uiLayoutColumn(pa->layout, 0); + block= uiLayoutGetBlock(col); + but= uiDefBut(block, BUT, B_IPO_DEPCHANGE, "Add Variable", 0, 0, 10*UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0, 0, "Add a new target variable for this Driver"); + uiButSetFunc(but, driver_add_var_cb, driver, NULL); /* loop over targets, drawing them */ for (dtar= driver->targets.first; dtar; dtar= dtar->next) { - short height = (dtar->id) ? 80 : 60; + PointerRNA dtar_ptr; + uiLayout *box, *row; - /* panel behind buttons */ - uiDefBut(block, ROUNDBOX, B_REDR, "", 5, yco-height+25, 310, height, NULL, 5.0, 0.0, 12.0, 0, ""); + /* panel holding the buttons */ + box= uiLayoutBox(pa->layout); - /* variable name */ - uiDefButC(block, TEX, B_REDR, "Name: ", 10,yco,280,20, dtar->name, 0, 63, 0, 0, "Name of target variable (No spaces or dots are allowed. Also, must not start with a symbol or digit)."); + /* first row context info for driver */ + RNA_pointer_create(ale->id, &RNA_DriverTarget, dtar, &dtar_ptr); - /* remove button */ - but= uiDefIconBut(block, BUT, B_REDR, ICON_X, 290, yco, 20, 20, NULL, 0.0, 0.0, 0.0, 0.0, "Delete target variable."); - uiButSetFunc(but, driver_delete_var_cb, driver, dtar); + row= uiLayoutRow(box, 0); + block= uiLayoutGetBlock(row); + /* variable name */ + uiItemR(row, "", 0, &dtar_ptr, "name", 0); + + /* remove button */ + but= uiDefIconBut(block, BUT, B_REDR, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y, NULL, 0.0, 0.0, 0.0, 0.0, "Delete target variable."); + uiButSetFunc(but, driver_delete_var_cb, driver, dtar); - /* Target Object */ - uiDefBut(block, LABEL, 1, "Value:", 10, yco-30, 60, 20, NULL, 0.0, 0.0, 0, 0, ""); - uiDefIDPoinBut(block, test_obpoin_but, ID_OB, B_REDR, "Ob: ", 70, yco-30, 240, 20, &dtar->id, "Object to use as Driver target"); + /* Target ID */ + row= uiLayoutRow(box, 0); + uiTemplateAnyID(row, (bContext *)C, &dtar_ptr, "id", "id_type", "Value: "); - // XXX should we hide these technical details? + /* Target Property */ + // TODO: make this less technical... if (dtar->id) { - uiBlockBeginAlign(block); - /* RNA Path */ - RNA_pointer_create(ale->id, &RNA_DriverTarget, dtar, &rna_ptr); - uiDefButR(block, TEX, 0, "Path: ", 10, yco-50, 250, 20, &rna_ptr, "rna_path", 0, 0, 0, -1, -1, "RNA Path (from Driver Object) to property used as Driver."); - - /* Array Index */ - uiDefButI(block, NUM, B_REDR, "", 260,yco-50,50,20, &dtar->array_index, 0, INT_MAX, 0, 0, "Index to the specific property used as Driver if applicable."); - uiBlockEndAlign(block); + col= uiLayoutColumn(box, 1); + block= uiLayoutGetBlock(col); + /* rna path */ + // TODO: this needs path constructor widget + uiItemR(col, "Path", 0, &dtar_ptr, "rna_path", 0); + + /* array index */ + // TODO: this needs selector which limits it to ok values + uiItemR(col, "Index", 0, &dtar_ptr, "array_index", 0); } - - /* adjust y-coordinate for next target */ - yco -= height; - i++; } - + + /* cleanup */ MEM_freeN(ale); } @@ -373,8 +365,8 @@ static void do_graph_region_modifier_buttons(bContext *C, void *arg, int event) switch (event) { case B_REDR: case B_FMODIFIER_REDRAW: // XXX this should send depsgraph updates too - ED_area_tag_redraw(CTX_wm_area(C)); - return; /* no notifier! */ + WM_event_add_notifier(C, NC_ANIMATION, NULL); // XXX need a notifier specially for F-Modifiers + break; } } diff --git a/source/blender/makesrna/intern/rna_fcurve.c b/source/blender/makesrna/intern/rna_fcurve.c index 12a81afa2b5..271964bb483 100644 --- a/source/blender/makesrna/intern/rna_fcurve.c +++ b/source/blender/makesrna/intern/rna_fcurve.c @@ -32,6 +32,7 @@ #include "rna_internal.h" #include "DNA_anim_types.h" +#include "DNA_object_types.h" #include "DNA_scene_types.h" #include "MEM_guardedalloc.h" @@ -52,8 +53,6 @@ EnumPropertyItem fmodifier_type_items[] = { #ifdef RNA_RUNTIME -/* --------- */ - static StructRNA *rna_FModifierType_refine(struct PointerRNA *ptr) { FModifier *fcm= (FModifier *)ptr->data; @@ -82,6 +81,21 @@ static StructRNA *rna_FModifierType_refine(struct PointerRNA *ptr) /* ****************************** */ +#include "BKE_depsgraph.h" + +static void rna_ChannelDriver_update_data(bContext *C, PointerRNA *ptr) +{ + ID *id= ptr->id.data; + + // TODO: this really needs an update guard... + DAG_scene_sort(CTX_data_scene(C)); + DAG_id_flush_update(id, OB_RECALC_DATA); + + WM_event_add_notifier(C, NC_SCENE, id); +} + +/* ----------- */ + static StructRNA *rna_DriverTarget_id_typef(PointerRNA *ptr) { DriverTarget *dtar= (DriverTarget*)ptr->data; @@ -535,7 +549,8 @@ static void rna_def_drivertarget(BlenderRNA *brna) /* Variable Name */ prop= RNA_def_property(srna, "name", PROP_STRING, PROP_NONE); RNA_def_struct_name_property(srna, prop); - RNA_def_property_ui_text(prop, "Name", "Name to use in scripted expressions/functions."); + RNA_def_property_ui_text(prop, "Name", "Name to use in scripted expressions/functions. (No spaces or dots are allowed. Also, must not start with a symbol or digit)"); + //RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); // XXX disabled for now, until we can turn off auto updates /* Target Properties - ID-block to Drive */ prop= RNA_def_property(srna, "id", PROP_POINTER, PROP_NONE); @@ -544,20 +559,24 @@ static void rna_def_drivertarget(BlenderRNA *brna) RNA_def_property_editable_func(prop, "rna_DriverTarget_id_editable"); RNA_def_property_pointer_funcs(prop, NULL, NULL, "rna_DriverTarget_id_typef"); RNA_def_property_ui_text(prop, "ID", "ID-block that the specific property used can be found from"); + //RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); // XXX disabled for now, until we can turn off auto updates prop= RNA_def_property(srna, "id_type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_sdna(prop, NULL, "idtype"); RNA_def_property_enum_items(prop, id_type_items); RNA_def_property_enum_default(prop, ID_OB); RNA_def_property_ui_text(prop, "ID Type", "Type of ID-block that can be used."); + //RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); // XXX disabled for now, until we can turn off auto updates /* Target Properties - Property to Drive */ prop= RNA_def_property(srna, "rna_path", PROP_STRING, PROP_NONE); RNA_def_property_string_funcs(prop, "rna_DriverTarget_RnaPath_get", "rna_DriverTarget_RnaPath_length", "rna_DriverTarget_RnaPath_set"); RNA_def_property_ui_text(prop, "RNA Path", "RNA Path (from Object) to property used"); + //RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); // XXX disabled for now, until we can turn off auto updates prop= RNA_def_property(srna, "array_index", PROP_INT, PROP_NONE); RNA_def_property_ui_text(prop, "RNA Array Index", "Index to the specific property used (if applicable)"); + //RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); // XXX disabled for now, until we can turn off auto updates } static void rna_def_channeldriver(BlenderRNA *brna) @@ -579,10 +598,12 @@ static void rna_def_channeldriver(BlenderRNA *brna) prop= RNA_def_property(srna, "type", PROP_ENUM, PROP_NONE); RNA_def_property_enum_items(prop, prop_type_items); RNA_def_property_ui_text(prop, "Type", "Driver types."); + RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); /* String values */ prop= RNA_def_property(srna, "expression", PROP_STRING, PROP_NONE); RNA_def_property_ui_text(prop, "Expression", "Expression to use for Scripted Expression."); + //RNA_def_property_update(prop, 0, "rna_ChannelDriver_update_data"); // XXX disabled for now, until we can turn off auto updates /* Collections */ prop= RNA_def_property(srna, "targets", PROP_COLLECTION, PROP_NONE);