Drivers UI - Converting to Layout Engine

* Converted Drivers UI to mostly use the Layout Engine
* All the buttons that perform actions are not operators yet (the code for that would be quite icky still)

* I've added some (commented out) calls for the property definitions of Driver properties to perform Depsgraph updates. I've left these commented out until we have the option to turn off auto-updates, since with driver editing, that could be very dangerous.

* Drivers can now (in theory) use any ID-block, using the Any-ID template added earlier. However, be warned that the stupid depsgraph won't be able to cope with most of these cases.


TODO: 
- more fancy widgets for RNA-Path and Index will come later
This commit is contained in:
2009-10-14 11:57:26 +00:00
parent 3d57e84088
commit cd202a1a24
4 changed files with 99 additions and 87 deletions

View File

@@ -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);

View File

@@ -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... */

View File

@@ -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;
}
}

View File

@@ -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);