Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/editors/space_graph/graph_buttons.c')
-rw-r--r--source/blender/editors/space_graph/graph_buttons.c2121
1 files changed, 1150 insertions, 971 deletions
diff --git a/source/blender/editors/space_graph/graph_buttons.c b/source/blender/editors/space_graph/graph_buttons.c
index a4d7b5e9fc9..ac77095cbe2 100644
--- a/source/blender/editors/space_graph/graph_buttons.c
+++ b/source/blender/editors/space_graph/graph_buttons.c
@@ -21,7 +21,6 @@
* \ingroup spgraph
*/
-
#include <string.h>
#include <stdio.h>
#include <math.h>
@@ -64,7 +63,7 @@
#include "UI_interface.h"
#include "UI_resources.h"
-#include "graph_intern.h" // own include
+#include "graph_intern.h" // own include
/* ******************* graph editor space & buttons ************** */
@@ -74,33 +73,33 @@
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;
+ 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 bool graph_panel_poll(const bContext *C, PanelType *UNUSED(pt))
{
- return graph_panel_context(C, NULL, NULL);
+ return graph_panel_context(C, NULL, NULL);
}
/* -------------- */
@@ -108,104 +107,104 @@ static bool graph_panel_poll(const bContext *C, PanelType *UNUSED(pt))
/* Graph Editor View Settings */
static void graph_panel_view(const bContext *C, Panel *pa)
{
- bScreen *sc = CTX_wm_screen(C);
- SpaceGraph *sipo = CTX_wm_space_graph(C);
- Scene *scene = CTX_data_scene(C);
- PointerRNA spaceptr, sceneptr;
- uiLayout *col, *sub, *row;
-
- /* get RNA pointers for use when creating the UI elements */
- RNA_id_pointer_create(&scene->id, &sceneptr);
- RNA_pointer_create(&sc->id, &RNA_SpaceGraphEditor, sipo, &spaceptr);
-
- /* 2D-Cursor */
- col = uiLayoutColumn(pa->layout, false);
- uiItemR(col, &spaceptr, "show_cursor", 0, NULL, ICON_NONE);
-
- sub = uiLayoutColumn(col, true);
- uiLayoutSetActive(sub, RNA_boolean_get(&spaceptr, "show_cursor"));
- uiItemO(sub, IFACE_("Cursor from Selection"), ICON_NONE, "GRAPH_OT_frame_jump");
-
- sub = uiLayoutColumn(col, true);
- uiLayoutSetActive(sub, RNA_boolean_get(&spaceptr, "show_cursor"));
- row = uiLayoutSplit(sub, 0.7f, true);
- if (sipo->mode == SIPO_MODE_DRIVERS)
- uiItemR(row, &spaceptr, "cursor_position_x", 0, IFACE_("Cursor X"), ICON_NONE);
- else
- uiItemR(row, &sceneptr, "frame_current", 0, IFACE_("Cursor X"), ICON_NONE);
- uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_CFRA);
-
- row = uiLayoutSplit(sub, 0.7f, true);
- uiItemR(row, &spaceptr, "cursor_position_y", 0, IFACE_("Cursor Y"), ICON_NONE);
- uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_VALUE);
+ bScreen *sc = CTX_wm_screen(C);
+ SpaceGraph *sipo = CTX_wm_space_graph(C);
+ Scene *scene = CTX_data_scene(C);
+ PointerRNA spaceptr, sceneptr;
+ uiLayout *col, *sub, *row;
+
+ /* get RNA pointers for use when creating the UI elements */
+ RNA_id_pointer_create(&scene->id, &sceneptr);
+ RNA_pointer_create(&sc->id, &RNA_SpaceGraphEditor, sipo, &spaceptr);
+
+ /* 2D-Cursor */
+ col = uiLayoutColumn(pa->layout, false);
+ uiItemR(col, &spaceptr, "show_cursor", 0, NULL, ICON_NONE);
+
+ sub = uiLayoutColumn(col, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(&spaceptr, "show_cursor"));
+ uiItemO(sub, IFACE_("Cursor from Selection"), ICON_NONE, "GRAPH_OT_frame_jump");
+
+ sub = uiLayoutColumn(col, true);
+ uiLayoutSetActive(sub, RNA_boolean_get(&spaceptr, "show_cursor"));
+ row = uiLayoutSplit(sub, 0.7f, true);
+ if (sipo->mode == SIPO_MODE_DRIVERS)
+ uiItemR(row, &spaceptr, "cursor_position_x", 0, IFACE_("Cursor X"), ICON_NONE);
+ else
+ uiItemR(row, &sceneptr, "frame_current", 0, IFACE_("Cursor X"), ICON_NONE);
+ uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_CFRA);
+
+ row = uiLayoutSplit(sub, 0.7f, true);
+ uiItemR(row, &spaceptr, "cursor_position_y", 0, IFACE_("Cursor Y"), ICON_NONE);
+ uiItemEnumO(row, "GRAPH_OT_snap", IFACE_("To Keys"), 0, "type", GRAPHKEYS_SNAP_VALUE);
}
/* ******************* active F-Curve ************** */
static void graph_panel_properties(const bContext *C, Panel *pa)
{
- bAnimListElem *ale;
- FCurve *fcu;
- PointerRNA fcu_ptr;
- uiLayout *layout = pa->layout;
- uiLayout *col, *row, *sub;
- char name[256];
- int icon = 0;
-
- if (!graph_panel_context(C, &ale, &fcu))
- return;
-
- /* F-Curve pointer */
- RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr);
-
- /* user-friendly 'name' for F-Curve */
- col = uiLayoutColumn(layout, false);
- if (ale->type == ANIMTYPE_FCURVE) {
- /* get user-friendly name for F-Curve */
- icon = getname_anim_fcurve(name, ale->id, fcu);
- }
- else {
- /* NLA Control Curve, etc. */
- const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
-
- /* get name */
- if (acf && acf->name) {
- acf->name(ale, name);
- }
- else {
- strcpy(name, IFACE_("<invalid>"));
- icon = ICON_ERROR;
- }
-
- /* icon */
- if (ale->type == ANIMTYPE_NLACURVE)
- icon = ICON_NLA;
- }
- uiItemL(col, name, icon);
-
- /* RNA-Path Editing - only really should be enabled when things aren't working */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetEnabled(col, (fcu->flag & FCURVE_DISABLED) != 0);
- uiItemR(col, &fcu_ptr, "data_path", 0, "", ICON_RNA);
- uiItemR(col, &fcu_ptr, "array_index", 0, NULL, ICON_NONE);
-
- /* color settings */
- col = uiLayoutColumn(layout, true);
- uiItemL(col, IFACE_("Display Color:"), ICON_NONE);
-
- row = uiLayoutRow(col, true);
- uiItemR(row, &fcu_ptr, "color_mode", 0, "", ICON_NONE);
-
- sub = uiLayoutRow(row, true);
- uiLayoutSetEnabled(sub, (fcu->color_mode == FCURVE_COLOR_CUSTOM));
- uiItemR(sub, &fcu_ptr, "color", 0, "", ICON_NONE);
-
- /* smoothing setting */
- col = uiLayoutColumn(layout, true);
- uiItemL(col, IFACE_("Auto Handle Smoothing:"), ICON_NONE);
- uiItemR(col, &fcu_ptr, "auto_smoothing", 0, "", ICON_NONE);
-
- MEM_freeN(ale);
+ bAnimListElem *ale;
+ FCurve *fcu;
+ PointerRNA fcu_ptr;
+ uiLayout *layout = pa->layout;
+ uiLayout *col, *row, *sub;
+ char name[256];
+ int icon = 0;
+
+ if (!graph_panel_context(C, &ale, &fcu))
+ return;
+
+ /* F-Curve pointer */
+ RNA_pointer_create(ale->id, &RNA_FCurve, fcu, &fcu_ptr);
+
+ /* user-friendly 'name' for F-Curve */
+ col = uiLayoutColumn(layout, false);
+ if (ale->type == ANIMTYPE_FCURVE) {
+ /* get user-friendly name for F-Curve */
+ icon = getname_anim_fcurve(name, ale->id, fcu);
+ }
+ else {
+ /* NLA Control Curve, etc. */
+ const bAnimChannelType *acf = ANIM_channel_get_typeinfo(ale);
+
+ /* get name */
+ if (acf && acf->name) {
+ acf->name(ale, name);
+ }
+ else {
+ strcpy(name, IFACE_("<invalid>"));
+ icon = ICON_ERROR;
+ }
+
+ /* icon */
+ if (ale->type == ANIMTYPE_NLACURVE)
+ icon = ICON_NLA;
+ }
+ uiItemL(col, name, icon);
+
+ /* RNA-Path Editing - only really should be enabled when things aren't working */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetEnabled(col, (fcu->flag & FCURVE_DISABLED) != 0);
+ uiItemR(col, &fcu_ptr, "data_path", 0, "", ICON_RNA);
+ uiItemR(col, &fcu_ptr, "array_index", 0, NULL, ICON_NONE);
+
+ /* color settings */
+ col = uiLayoutColumn(layout, true);
+ uiItemL(col, IFACE_("Display Color:"), ICON_NONE);
+
+ row = uiLayoutRow(col, true);
+ uiItemR(row, &fcu_ptr, "color_mode", 0, "", ICON_NONE);
+
+ sub = uiLayoutRow(row, true);
+ uiLayoutSetEnabled(sub, (fcu->color_mode == FCURVE_COLOR_CUSTOM));
+ uiItemR(sub, &fcu_ptr, "color", 0, "", ICON_NONE);
+
+ /* smoothing setting */
+ col = uiLayoutColumn(layout, true);
+ uiItemL(col, IFACE_("Auto Handle Smoothing:"), ICON_NONE);
+ uiItemR(col, &fcu_ptr, "auto_smoothing", 0, "", ICON_NONE);
+
+ MEM_freeN(ale);
}
/* ******************* active Keyframe ************** */
@@ -213,66 +212,68 @@ static void graph_panel_properties(const bContext *C, Panel *pa)
/* get 'active' keyframe for panel editing */
static short get_active_fcurve_keyframe_edit(FCurve *fcu, BezTriple **bezt, BezTriple **prevbezt)
{
- BezTriple *b;
- int i;
-
- /* zero the pointers */
- *bezt = *prevbezt = NULL;
-
- /* sanity checks */
- if ((fcu->bezt == NULL) || (fcu->totvert == 0))
- return 0;
-
- /* find first selected keyframe for now, and call it the active one
- * - this is a reasonable assumption, given that whenever anyone
- * wants to edit numerically, there is likely to only be 1 vert selected
- */
- for (i = 0, b = fcu->bezt; i < fcu->totvert; i++, b++) {
- if (BEZT_ISSEL_ANY(b)) {
- /* found
- * - 'previous' is either the one before, of the keyframe itself (which is still fine)
- * XXX: we can just make this null instead if needed
- */
- *prevbezt = (i > 0) ? b - 1 : b;
- *bezt = b;
-
- return 1;
- }
- }
-
- /* not found */
- return 0;
+ BezTriple *b;
+ int i;
+
+ /* zero the pointers */
+ *bezt = *prevbezt = NULL;
+
+ /* sanity checks */
+ if ((fcu->bezt == NULL) || (fcu->totvert == 0))
+ return 0;
+
+ /* find first selected keyframe for now, and call it the active one
+ * - this is a reasonable assumption, given that whenever anyone
+ * wants to edit numerically, there is likely to only be 1 vert selected
+ */
+ for (i = 0, b = fcu->bezt; i < fcu->totvert; i++, b++) {
+ if (BEZT_ISSEL_ANY(b)) {
+ /* found
+ * - 'previous' is either the one before, of the keyframe itself (which is still fine)
+ * XXX: we can just make this null instead if needed
+ */
+ *prevbezt = (i > 0) ? b - 1 : b;
+ *bezt = b;
+
+ return 1;
+ }
+ }
+
+ /* not found */
+ return 0;
}
/* update callback for active keyframe properties - base updates stuff */
-static void graphedit_activekey_update_cb(bContext *UNUSED(C), void *fcu_ptr, void *UNUSED(bezt_ptr))
+static void graphedit_activekey_update_cb(bContext *UNUSED(C),
+ void *fcu_ptr,
+ void *UNUSED(bezt_ptr))
{
- FCurve *fcu = (FCurve *)fcu_ptr;
+ FCurve *fcu = (FCurve *)fcu_ptr;
- /* make sure F-Curve and its handles are still valid after this editing */
- sort_time_fcurve(fcu);
- calchandles_fcurve(fcu);
+ /* make sure F-Curve and its handles are still valid after this editing */
+ sort_time_fcurve(fcu);
+ calchandles_fcurve(fcu);
}
/* update callback for active keyframe properties - handle-editing wrapper */
static void graphedit_activekey_handles_cb(bContext *C, void *fcu_ptr, void *bezt_ptr)
{
- BezTriple *bezt = (BezTriple *)bezt_ptr;
-
- /* since editing the handles, make sure they're set to types which are receptive to editing
- * see transform_conversions.c :: createTransGraphEditData(), last step in second loop
- */
- if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) && ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) {
- /* by changing to aligned handles, these can now be moved... */
- bezt->h1 = HD_ALIGN;
- bezt->h2 = HD_ALIGN;
- }
- else {
- BKE_nurb_bezt_handle_test(bezt, true);
- }
-
- /* now call standard updates */
- graphedit_activekey_update_cb(C, fcu_ptr, bezt_ptr);
+ BezTriple *bezt = (BezTriple *)bezt_ptr;
+
+ /* since editing the handles, make sure they're set to types which are receptive to editing
+ * see transform_conversions.c :: createTransGraphEditData(), last step in second loop
+ */
+ if (ELEM(bezt->h1, HD_AUTO, HD_AUTO_ANIM) && ELEM(bezt->h2, HD_AUTO, HD_AUTO_ANIM)) {
+ /* by changing to aligned handles, these can now be moved... */
+ bezt->h1 = HD_ALIGN;
+ bezt->h2 = HD_ALIGN;
+ }
+ else {
+ BKE_nurb_bezt_handle_test(bezt, true);
+ }
+
+ /* now call standard updates */
+ graphedit_activekey_update_cb(C, fcu_ptr, bezt_ptr);
}
/* update callback for editing coordinates of right handle in active keyframe properties
@@ -281,766 +282,943 @@ static void graphedit_activekey_handles_cb(bContext *C, void *fcu_ptr, void *bez
*/
static void graphedit_activekey_left_handle_coord_cb(bContext *C, void *fcu_ptr, void *bezt_ptr)
{
- BezTriple *bezt = (BezTriple *)bezt_ptr;
+ BezTriple *bezt = (BezTriple *)bezt_ptr;
- const char f1 = bezt->f1;
- const char f3 = bezt->f3;
+ const char f1 = bezt->f1;
+ const char f3 = bezt->f3;
- bezt->f1 |= SELECT;
- bezt->f3 &= ~SELECT;
+ bezt->f1 |= SELECT;
+ bezt->f3 &= ~SELECT;
- /* perform normal updates NOW */
- graphedit_activekey_handles_cb(C, fcu_ptr, bezt_ptr);
+ /* perform normal updates NOW */
+ graphedit_activekey_handles_cb(C, fcu_ptr, bezt_ptr);
- /* restore selection state so that no-one notices this hack */
- bezt->f1 = f1;
- bezt->f3 = f3;
+ /* restore selection state so that no-one notices this hack */
+ bezt->f1 = f1;
+ bezt->f3 = f3;
}
static void graphedit_activekey_right_handle_coord_cb(bContext *C, void *fcu_ptr, void *bezt_ptr)
{
- BezTriple *bezt = (BezTriple *)bezt_ptr;
+ BezTriple *bezt = (BezTriple *)bezt_ptr;
- /* original state of handle selection - to be restored after performing the recalculation */
- const char f1 = bezt->f1;
- const char f3 = bezt->f3;
+ /* original state of handle selection - to be restored after performing the recalculation */
+ const char f1 = bezt->f1;
+ const char f3 = bezt->f3;
- /* temporarily make it so that only the right handle is selected, so that updates go correctly
- * (i.e. it now acts as if we've just transforming the vert when it is selected by itself)
- */
- bezt->f1 &= ~SELECT;
- bezt->f3 |= SELECT;
+ /* temporarily make it so that only the right handle is selected, so that updates go correctly
+ * (i.e. it now acts as if we've just transforming the vert when it is selected by itself)
+ */
+ bezt->f1 &= ~SELECT;
+ bezt->f3 |= SELECT;
- /* perform normal updates NOW */
- graphedit_activekey_handles_cb(C, fcu_ptr, bezt_ptr);
+ /* perform normal updates NOW */
+ graphedit_activekey_handles_cb(C, fcu_ptr, bezt_ptr);
- /* restore selection state so that no-one notices this hack */
- bezt->f1 = f1;
- bezt->f3 = f3;
+ /* restore selection state so that no-one notices this hack */
+ bezt->f1 = f1;
+ bezt->f3 = f3;
}
static void graph_panel_key_properties(const bContext *C, Panel *pa)
{
- bAnimListElem *ale;
- FCurve *fcu;
- BezTriple *bezt, *prevbezt;
-
- uiLayout *layout = pa->layout;
- uiLayout *col;
- uiBlock *block;
-
- if (!graph_panel_context(C, &ale, &fcu))
- return;
-
- block = uiLayoutGetBlock(layout);
- /* UI_block_func_handle_set(block, do_graph_region_buttons, NULL); */
-
- /* only show this info if there are keyframes to edit */
- if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) {
- PointerRNA bezt_ptr, id_ptr, fcu_prop_ptr;
- PropertyRNA *fcu_prop = NULL;
- uiBut *but;
- int unit = B_UNIT_NONE;
-
- /* RNA pointer to keyframe, to allow editing */
- RNA_pointer_create(ale->id, &RNA_Keyframe, bezt, &bezt_ptr);
-
- /* get property that F-Curve affects, for some unit-conversion magic */
- RNA_id_pointer_create(ale->id, &id_ptr);
- if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &fcu_prop_ptr, &fcu_prop)) {
- /* determine the unit for this property */
- unit = RNA_SUBTYPE_UNIT(RNA_property_subtype(fcu_prop));
- }
-
- /* interpolation */
- col = uiLayoutColumn(layout, false);
- if (fcu->flag & FCURVE_DISCRETE_VALUES) {
- uiLayout *split = uiLayoutSplit(col, 0.33f, true);
- uiItemL(split, IFACE_("Interpolation:"), ICON_NONE);
- uiItemL(split, IFACE_("None for Enum/Boolean"), ICON_IPO_CONSTANT);
- }
- else {
- uiItemR(col, &bezt_ptr, "interpolation", 0, NULL, ICON_NONE);
- }
-
- /* easing type */
- if (bezt->ipo > BEZT_IPO_BEZ)
- uiItemR(col, &bezt_ptr, "easing", 0, NULL, 0);
-
- /* easing extra */
- switch (bezt->ipo) {
- case BEZT_IPO_BACK:
- col = uiLayoutColumn(layout, 1);
- uiItemR(col, &bezt_ptr, "back", 0, NULL, 0);
- break;
- case BEZT_IPO_ELASTIC:
- col = uiLayoutColumn(layout, 1);
- uiItemR(col, &bezt_ptr, "amplitude", 0, NULL, 0);
- uiItemR(col, &bezt_ptr, "period", 0, NULL, 0);
- break;
- default:
- break;
- }
-
- /* numerical coordinate editing
- * - we use the button-versions of the calls so that we can attach special update handlers
- * and unit conversion magic that cannot be achieved using a purely RNA-approach
- */
- col = uiLayoutColumn(layout, true);
- /* keyframe itself */
- {
- uiItemL(col, IFACE_("Key:"), ICON_NONE);
-
- but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Frame:"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "co", 0, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
-
- but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, IFACE_("Value:"), 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "co", 1, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
- UI_but_unit_type_set(but, unit);
- }
-
- /* previous handle - only if previous was Bezier interpolation */
- if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
- uiItemL(col, IFACE_("Left Handle:"), ICON_NONE);
-
- but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "handle_left", 0, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
-
- but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "handle_left", 1, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
- UI_but_unit_type_set(but, unit);
-
- /* XXX: with label? */
- but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "handle_left_type", 0, 0, 0, -1, -1, "Type of left handle");
- UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
- }
-
- /* next handle - only if current is Bezier interpolation */
- if (bezt->ipo == BEZT_IPO_BEZ) {
- /* NOTE: special update callbacks are needed on the coords here due to T39911 */
- uiItemL(col, IFACE_("Right Handle:"), ICON_NONE);
-
- but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "X:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "handle_right", 0, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
-
- but = uiDefButR(block, UI_BTYPE_NUM, B_REDR, "Y:", 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "handle_right", 1, 0, 0, -1, -1, NULL);
- UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
- UI_but_unit_type_set(but, unit);
-
- /* XXX: with label? */
- but = uiDefButR(block, UI_BTYPE_MENU, B_REDR, NULL, 0, 0, UI_UNIT_X, UI_UNIT_Y,
- &bezt_ptr, "handle_right_type", 0, 0, 0, -1, -1, "Type of right handle");
- UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
- }
- }
- else {
- if ((fcu->bezt == NULL) && (fcu->modifiers.first)) {
- /* modifiers only - so no keyframes to be active */
- uiItemL(layout, IFACE_("F-Curve only has F-Modifiers"), ICON_NONE);
- uiItemL(layout, IFACE_("See Modifiers panel below"), ICON_INFO);
- }
- else if (fcu->fpt) {
- /* samples only */
- uiItemL(layout, IFACE_("F-Curve doesn't have any keyframes as it only contains sampled points"),
- ICON_NONE);
- }
- else
- uiItemL(layout, IFACE_("No active keyframe on F-Curve"), ICON_NONE);
- }
-
- MEM_freeN(ale);
+ bAnimListElem *ale;
+ FCurve *fcu;
+ BezTriple *bezt, *prevbezt;
+
+ uiLayout *layout = pa->layout;
+ uiLayout *col;
+ uiBlock *block;
+
+ if (!graph_panel_context(C, &ale, &fcu))
+ return;
+
+ block = uiLayoutGetBlock(layout);
+ /* UI_block_func_handle_set(block, do_graph_region_buttons, NULL); */
+
+ /* only show this info if there are keyframes to edit */
+ if (get_active_fcurve_keyframe_edit(fcu, &bezt, &prevbezt)) {
+ PointerRNA bezt_ptr, id_ptr, fcu_prop_ptr;
+ PropertyRNA *fcu_prop = NULL;
+ uiBut *but;
+ int unit = B_UNIT_NONE;
+
+ /* RNA pointer to keyframe, to allow editing */
+ RNA_pointer_create(ale->id, &RNA_Keyframe, bezt, &bezt_ptr);
+
+ /* get property that F-Curve affects, for some unit-conversion magic */
+ RNA_id_pointer_create(ale->id, &id_ptr);
+ if (RNA_path_resolve_property(&id_ptr, fcu->rna_path, &fcu_prop_ptr, &fcu_prop)) {
+ /* determine the unit for this property */
+ unit = RNA_SUBTYPE_UNIT(RNA_property_subtype(fcu_prop));
+ }
+
+ /* interpolation */
+ col = uiLayoutColumn(layout, false);
+ if (fcu->flag & FCURVE_DISCRETE_VALUES) {
+ uiLayout *split = uiLayoutSplit(col, 0.33f, true);
+ uiItemL(split, IFACE_("Interpolation:"), ICON_NONE);
+ uiItemL(split, IFACE_("None for Enum/Boolean"), ICON_IPO_CONSTANT);
+ }
+ else {
+ uiItemR(col, &bezt_ptr, "interpolation", 0, NULL, ICON_NONE);
+ }
+
+ /* easing type */
+ if (bezt->ipo > BEZT_IPO_BEZ)
+ uiItemR(col, &bezt_ptr, "easing", 0, NULL, 0);
+
+ /* easing extra */
+ switch (bezt->ipo) {
+ case BEZT_IPO_BACK:
+ col = uiLayoutColumn(layout, 1);
+ uiItemR(col, &bezt_ptr, "back", 0, NULL, 0);
+ break;
+ case BEZT_IPO_ELASTIC:
+ col = uiLayoutColumn(layout, 1);
+ uiItemR(col, &bezt_ptr, "amplitude", 0, NULL, 0);
+ uiItemR(col, &bezt_ptr, "period", 0, NULL, 0);
+ break;
+ default:
+ break;
+ }
+
+ /* numerical coordinate editing
+ * - we use the button-versions of the calls so that we can attach special update handlers
+ * and unit conversion magic that cannot be achieved using a purely RNA-approach
+ */
+ col = uiLayoutColumn(layout, true);
+ /* keyframe itself */
+ {
+ uiItemL(col, IFACE_("Key:"), ICON_NONE);
+
+ but = uiDefButR(block,
+ UI_BTYPE_NUM,
+ B_REDR,
+ IFACE_("Frame:"),
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "co",
+ 0,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
+
+ but = uiDefButR(block,
+ UI_BTYPE_NUM,
+ B_REDR,
+ IFACE_("Value:"),
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "co",
+ 1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, graphedit_activekey_update_cb, fcu, bezt);
+ UI_but_unit_type_set(but, unit);
+ }
+
+ /* previous handle - only if previous was Bezier interpolation */
+ if ((prevbezt) && (prevbezt->ipo == BEZT_IPO_BEZ)) {
+ uiItemL(col, IFACE_("Left Handle:"), ICON_NONE);
+
+ but = uiDefButR(block,
+ UI_BTYPE_NUM,
+ B_REDR,
+ "X:",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "handle_left",
+ 0,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
+
+ but = uiDefButR(block,
+ UI_BTYPE_NUM,
+ B_REDR,
+ "Y:",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "handle_left",
+ 1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, graphedit_activekey_left_handle_coord_cb, fcu, bezt);
+ UI_but_unit_type_set(but, unit);
+
+ /* XXX: with label? */
+ but = uiDefButR(block,
+ UI_BTYPE_MENU,
+ B_REDR,
+ NULL,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "handle_left_type",
+ 0,
+ 0,
+ 0,
+ -1,
+ -1,
+ "Type of left handle");
+ UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
+ }
+
+ /* next handle - only if current is Bezier interpolation */
+ if (bezt->ipo == BEZT_IPO_BEZ) {
+ /* NOTE: special update callbacks are needed on the coords here due to T39911 */
+ uiItemL(col, IFACE_("Right Handle:"), ICON_NONE);
+
+ but = uiDefButR(block,
+ UI_BTYPE_NUM,
+ B_REDR,
+ "X:",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "handle_right",
+ 0,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
+
+ but = uiDefButR(block,
+ UI_BTYPE_NUM,
+ B_REDR,
+ "Y:",
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "handle_right",
+ 1,
+ 0,
+ 0,
+ -1,
+ -1,
+ NULL);
+ UI_but_func_set(but, graphedit_activekey_right_handle_coord_cb, fcu, bezt);
+ UI_but_unit_type_set(but, unit);
+
+ /* XXX: with label? */
+ but = uiDefButR(block,
+ UI_BTYPE_MENU,
+ B_REDR,
+ NULL,
+ 0,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ &bezt_ptr,
+ "handle_right_type",
+ 0,
+ 0,
+ 0,
+ -1,
+ -1,
+ "Type of right handle");
+ UI_but_func_set(but, graphedit_activekey_handles_cb, fcu, bezt);
+ }
+ }
+ else {
+ if ((fcu->bezt == NULL) && (fcu->modifiers.first)) {
+ /* modifiers only - so no keyframes to be active */
+ uiItemL(layout, IFACE_("F-Curve only has F-Modifiers"), ICON_NONE);
+ uiItemL(layout, IFACE_("See Modifiers panel below"), ICON_INFO);
+ }
+ else if (fcu->fpt) {
+ /* samples only */
+ uiItemL(layout,
+ IFACE_("F-Curve doesn't have any keyframes as it only contains sampled points"),
+ ICON_NONE);
+ }
+ else
+ uiItemL(layout, IFACE_("No active keyframe on F-Curve"), ICON_NONE);
+ }
+
+ MEM_freeN(ale);
}
/* ******************* drivers ******************************** */
-#define B_IPO_DEPCHANGE 10
+#define B_IPO_DEPCHANGE 10
static void do_graph_region_driver_buttons(bContext *C, void *id_v, int event)
{
- Main *bmain = CTX_data_main(C);
- Scene *scene = CTX_data_scene(C);
-
- switch (event) {
- case B_IPO_DEPCHANGE:
- {
- /* Was not actually run ever (NULL always passed as arg to this callback).
- * If needed again, will need to check how to pass both fcurve and ID... :/ */
+ Main *bmain = CTX_data_main(C);
+ Scene *scene = CTX_data_scene(C);
+
+ switch (event) {
+ case B_IPO_DEPCHANGE: {
+ /* Was not actually run ever (NULL always passed as arg to this callback).
+ * If needed again, will need to check how to pass both fcurve and ID... :/ */
#if 0
- /* force F-Curve & Driver to get re-evaluated (same as the old Update Dependencies) */
- FCurve *fcu = (FCurve *)fcu_v;
- ChannelDriver *driver = (fcu) ? fcu->driver : NULL;
-
- /* clear invalid flags */
- if (fcu) {
- fcu->flag &= ~FCURVE_DISABLED;
- driver->flag &= ~DRIVER_FLAG_INVALID;
- }
+ /* force F-Curve & Driver to get re-evaluated (same as the old Update Dependencies) */
+ FCurve *fcu = (FCurve *)fcu_v;
+ ChannelDriver *driver = (fcu) ? fcu->driver : NULL;
+
+ /* clear invalid flags */
+ if (fcu) {
+ fcu->flag &= ~FCURVE_DISABLED;
+ driver->flag &= ~DRIVER_FLAG_INVALID;
+ }
#endif
- ID *id = id_v;
- AnimData *adt = BKE_animdata_from_id(id);
-
- /* rebuild depsgraph for the new deps, and ensure COW copies get flushed. */
- DEG_relations_tag_update(bmain);
- DEG_id_tag_update_ex(bmain, id, ID_RECALC_COPY_ON_WRITE);
- if (adt != NULL) {
- if (adt->action != NULL) {
- DEG_id_tag_update_ex(bmain, &adt->action->id, ID_RECALC_COPY_ON_WRITE);
- }
- if (adt->tmpact != NULL) {
- DEG_id_tag_update_ex(bmain, &adt->tmpact->id, ID_RECALC_COPY_ON_WRITE);
- }
- }
-
- break;
- }
- }
-
- /* default for now */
- WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); // XXX could use better notifier
+ ID *id = id_v;
+ AnimData *adt = BKE_animdata_from_id(id);
+
+ /* rebuild depsgraph for the new deps, and ensure COW copies get flushed. */
+ DEG_relations_tag_update(bmain);
+ DEG_id_tag_update_ex(bmain, id, ID_RECALC_COPY_ON_WRITE);
+ if (adt != NULL) {
+ if (adt->action != NULL) {
+ DEG_id_tag_update_ex(bmain, &adt->action->id, ID_RECALC_COPY_ON_WRITE);
+ }
+ if (adt->tmpact != NULL) {
+ DEG_id_tag_update_ex(bmain, &adt->tmpact->id, ID_RECALC_COPY_ON_WRITE);
+ }
+ }
+
+ break;
+ }
+ }
+
+ /* default for now */
+ WM_event_add_notifier(C, NC_SCENE | ND_FRAME, scene); // XXX could use better notifier
}
/* callback to add a target variable to the active driver */
static void driver_add_var_cb(bContext *C, void *driver_v, void *UNUSED(arg))
{
- ChannelDriver *driver = (ChannelDriver *)driver_v;
+ ChannelDriver *driver = (ChannelDriver *)driver_v;
- /* add a new variable */
- driver_add_new_variable(driver);
- ED_undo_push(C, "Add Driver Variable");
+ /* add a new variable */
+ driver_add_new_variable(driver);
+ ED_undo_push(C, "Add Driver Variable");
}
/* callback to remove target variable from active driver */
static void driver_delete_var_cb(bContext *C, void *driver_v, void *dvar_v)
{
- ChannelDriver *driver = (ChannelDriver *)driver_v;
- DriverVar *dvar = (DriverVar *)dvar_v;
+ ChannelDriver *driver = (ChannelDriver *)driver_v;
+ DriverVar *dvar = (DriverVar *)dvar_v;
- /* remove the active variable */
- driver_free_variable_ex(driver, dvar);
- ED_undo_push(C, "Delete Driver Variable");
+ /* remove the active variable */
+ driver_free_variable_ex(driver, dvar);
+ ED_undo_push(C, "Delete Driver Variable");
}
/* callback to report why a driver variable is invalid */
static void driver_dvar_invalid_name_query_cb(bContext *C, void *dvar_v, void *UNUSED(arg))
{
- uiPopupMenu *pup = UI_popup_menu_begin(C, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Invalid Variable Name"), ICON_NONE);
- uiLayout *layout = UI_popup_menu_layout(pup);
-
- DriverVar *dvar = (DriverVar *)dvar_v;
-
- if (dvar->flag & DVAR_FLAG_INVALID_EMPTY) {
- uiItemL(layout, "It cannot be left blank", ICON_ERROR);
- }
- if (dvar->flag & DVAR_FLAG_INVALID_START_NUM) {
- uiItemL(layout, "It cannot start with a number", ICON_ERROR);
- }
- if (dvar->flag & DVAR_FLAG_INVALID_START_CHAR) {
- uiItemL(layout,
- "It cannot start with a special character,"
- " including '$', '@', '!', '~', '+', '-', '_', '.', or ' '",
- ICON_NONE);
- }
- if (dvar->flag & DVAR_FLAG_INVALID_HAS_SPACE) {
- uiItemL(layout, "It cannot contain spaces (e.g. 'a space')", ICON_ERROR);
- }
- if (dvar->flag & DVAR_FLAG_INVALID_HAS_DOT) {
- uiItemL(layout, "It cannot contain dots (e.g. 'a.dot')", ICON_ERROR);
- }
- if (dvar->flag & DVAR_FLAG_INVALID_HAS_SPECIAL) {
- uiItemL(layout, "It cannot contain special (non-alphabetical/numeric) characters", ICON_ERROR);
- }
- if (dvar->flag & DVAR_FLAG_INVALID_PY_KEYWORD) {
- uiItemL(layout, "It cannot be a reserved keyword in Python", ICON_INFO);
- }
-
- UI_popup_menu_end(C, pup);
+ uiPopupMenu *pup = UI_popup_menu_begin(
+ C, CTX_IFACE_(BLT_I18NCONTEXT_OPERATOR_DEFAULT, "Invalid Variable Name"), ICON_NONE);
+ uiLayout *layout = UI_popup_menu_layout(pup);
+
+ DriverVar *dvar = (DriverVar *)dvar_v;
+
+ if (dvar->flag & DVAR_FLAG_INVALID_EMPTY) {
+ uiItemL(layout, "It cannot be left blank", ICON_ERROR);
+ }
+ if (dvar->flag & DVAR_FLAG_INVALID_START_NUM) {
+ uiItemL(layout, "It cannot start with a number", ICON_ERROR);
+ }
+ if (dvar->flag & DVAR_FLAG_INVALID_START_CHAR) {
+ uiItemL(layout,
+ "It cannot start with a special character,"
+ " including '$', '@', '!', '~', '+', '-', '_', '.', or ' '",
+ ICON_NONE);
+ }
+ if (dvar->flag & DVAR_FLAG_INVALID_HAS_SPACE) {
+ uiItemL(layout, "It cannot contain spaces (e.g. 'a space')", ICON_ERROR);
+ }
+ if (dvar->flag & DVAR_FLAG_INVALID_HAS_DOT) {
+ uiItemL(layout, "It cannot contain dots (e.g. 'a.dot')", ICON_ERROR);
+ }
+ if (dvar->flag & DVAR_FLAG_INVALID_HAS_SPECIAL) {
+ uiItemL(layout, "It cannot contain special (non-alphabetical/numeric) characters", ICON_ERROR);
+ }
+ if (dvar->flag & DVAR_FLAG_INVALID_PY_KEYWORD) {
+ uiItemL(layout, "It cannot be a reserved keyword in Python", ICON_INFO);
+ }
+
+ UI_popup_menu_end(C, pup);
}
/* callback to reset the driver's flags */
static void driver_update_flags_cb(bContext *UNUSED(C), void *fcu_v, void *UNUSED(arg))
{
- FCurve *fcu = (FCurve *)fcu_v;
- ChannelDriver *driver = fcu->driver;
+ FCurve *fcu = (FCurve *)fcu_v;
+ ChannelDriver *driver = fcu->driver;
- /* clear invalid flags */
- fcu->flag &= ~FCURVE_DISABLED;
- driver->flag &= ~DRIVER_FLAG_INVALID;
+ /* clear invalid flags */
+ fcu->flag &= ~FCURVE_DISABLED;
+ driver->flag &= ~DRIVER_FLAG_INVALID;
}
/* drivers panel poll */
static bool graph_panel_drivers_poll(const bContext *C, PanelType *UNUSED(pt))
{
- SpaceGraph *sipo = CTX_wm_space_graph(C);
+ SpaceGraph *sipo = CTX_wm_space_graph(C);
- if (sipo->mode != SIPO_MODE_DRIVERS)
- return 0;
+ if (sipo->mode != SIPO_MODE_DRIVERS)
+ return 0;
- return graph_panel_context(C, NULL, NULL);
+ return graph_panel_context(C, NULL, NULL);
}
/* settings for 'single property' driver variable type */
static void graph_panel_driverVar__singleProp(uiLayout *layout, ID *id, DriverVar *dvar)
{
- DriverTarget *dtar = &dvar->targets[0];
- PointerRNA dtar_ptr;
- uiLayout *row, *col;
-
- /* initialize RNA pointer to the target */
- RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
-
- /* Target ID */
- row = uiLayoutRow(layout, false);
- uiLayoutSetRedAlert(row, ((dtar->flag & DTAR_FLAG_INVALID) && !dtar->id));
- uiTemplateAnyID(row, &dtar_ptr, "id", "id_type", IFACE_("Prop:"));
-
- /* Target Property */
- if (dtar->id) {
- PointerRNA root_ptr;
-
- /* get pointer for resolving the property selected */
- RNA_id_pointer_create(dtar->id, &root_ptr);
-
- /* rna path */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID));
- uiTemplatePathBuilder(col, &dtar_ptr, "data_path", &root_ptr, IFACE_("Path"));
- }
+ DriverTarget *dtar = &dvar->targets[0];
+ PointerRNA dtar_ptr;
+ uiLayout *row, *col;
+
+ /* initialize RNA pointer to the target */
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+
+ /* Target ID */
+ row = uiLayoutRow(layout, false);
+ uiLayoutSetRedAlert(row, ((dtar->flag & DTAR_FLAG_INVALID) && !dtar->id));
+ uiTemplateAnyID(row, &dtar_ptr, "id", "id_type", IFACE_("Prop:"));
+
+ /* Target Property */
+ if (dtar->id) {
+ PointerRNA root_ptr;
+
+ /* get pointer for resolving the property selected */
+ RNA_id_pointer_create(dtar->id, &root_ptr);
+
+ /* rna path */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID));
+ uiTemplatePathBuilder(col, &dtar_ptr, "data_path", &root_ptr, IFACE_("Path"));
+ }
}
/* settings for 'rotation difference' driver variable type */
/* FIXME: 1) Must be same armature for both dtars, 2) Alignment issues... */
static void graph_panel_driverVar__rotDiff(uiLayout *layout, ID *id, DriverVar *dvar)
{
- DriverTarget *dtar = &dvar->targets[0];
- DriverTarget *dtar2 = &dvar->targets[1];
- Object *ob1 = (Object *)dtar->id;
- Object *ob2 = (Object *)dtar2->id;
- PointerRNA dtar_ptr, dtar2_ptr;
- uiLayout *col;
-
- /* initialize RNA pointer to the target */
- RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
- RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
-
- /* Object 1 */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
- uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object 1"), ICON_NONE);
-
- if (dtar->id && GS(dtar->id->name) == ID_OB && ob1->pose) {
- PointerRNA tar_ptr;
-
- RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr);
- uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA);
- }
-
- /* Object 2 */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetRedAlert(col, (dtar2->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
- uiItemR(col, &dtar2_ptr, "id", 0, IFACE_("Object 2"), ICON_NONE);
-
- if (dtar2->id && GS(dtar2->id->name) == ID_OB && ob2->pose) {
- PointerRNA tar_ptr;
-
- RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr);
- uiItemPointerR(col, &dtar2_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA);
- }
+ DriverTarget *dtar = &dvar->targets[0];
+ DriverTarget *dtar2 = &dvar->targets[1];
+ Object *ob1 = (Object *)dtar->id;
+ Object *ob2 = (Object *)dtar2->id;
+ PointerRNA dtar_ptr, dtar2_ptr;
+ uiLayout *col;
+
+ /* initialize RNA pointer to the target */
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
+
+ /* Object 1 */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
+ uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object 1"), ICON_NONE);
+
+ if (dtar->id && GS(dtar->id->name) == ID_OB && ob1->pose) {
+ PointerRNA tar_ptr;
+
+ RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr);
+ uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA);
+ }
+
+ /* Object 2 */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetRedAlert(col, (dtar2->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
+ uiItemR(col, &dtar2_ptr, "id", 0, IFACE_("Object 2"), ICON_NONE);
+
+ if (dtar2->id && GS(dtar2->id->name) == ID_OB && ob2->pose) {
+ PointerRNA tar_ptr;
+
+ RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr);
+ uiItemPointerR(col, &dtar2_ptr, "bone_target", &tar_ptr, "bones", "", ICON_BONE_DATA);
+ }
}
/* settings for 'location difference' driver variable type */
static void graph_panel_driverVar__locDiff(uiLayout *layout, ID *id, DriverVar *dvar)
{
- DriverTarget *dtar = &dvar->targets[0];
- DriverTarget *dtar2 = &dvar->targets[1];
- Object *ob1 = (Object *)dtar->id;
- Object *ob2 = (Object *)dtar2->id;
- PointerRNA dtar_ptr, dtar2_ptr;
- uiLayout *col;
+ DriverTarget *dtar = &dvar->targets[0];
+ DriverTarget *dtar2 = &dvar->targets[1];
+ Object *ob1 = (Object *)dtar->id;
+ Object *ob2 = (Object *)dtar2->id;
+ PointerRNA dtar_ptr, dtar2_ptr;
+ uiLayout *col;
- /* initialize RNA pointer to the target */
- RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
- RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
+ /* initialize RNA pointer to the target */
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar2, &dtar2_ptr);
- /* Object 1 */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
- uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object 1"), ICON_NONE);
+ /* Object 1 */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
+ uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object 1"), ICON_NONE);
- if (dtar->id && GS(dtar->id->name) == ID_OB && ob1->pose) {
- PointerRNA tar_ptr;
+ if (dtar->id && GS(dtar->id->name) == ID_OB && ob1->pose) {
+ PointerRNA tar_ptr;
- RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr);
- uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
- }
+ RNA_pointer_create(dtar->id, &RNA_Pose, ob1->pose, &tar_ptr);
+ uiItemPointerR(
+ col, &dtar_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
+ }
- /* we can clear it again now - it's only needed when creating the ID/Bone fields */
- uiLayoutSetRedAlert(col, false);
+ /* we can clear it again now - it's only needed when creating the ID/Bone fields */
+ uiLayoutSetRedAlert(col, false);
- uiItemR(col, &dtar_ptr, "transform_space", 0, NULL, ICON_NONE);
+ uiItemR(col, &dtar_ptr, "transform_space", 0, NULL, ICON_NONE);
- /* Object 2 */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetRedAlert(col, (dtar2->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
- uiItemR(col, &dtar2_ptr, "id", 0, IFACE_("Object 2"), ICON_NONE);
+ /* Object 2 */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetRedAlert(col, (dtar2->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
+ uiItemR(col, &dtar2_ptr, "id", 0, IFACE_("Object 2"), ICON_NONE);
- if (dtar2->id && GS(dtar2->id->name) == ID_OB && ob2->pose) {
- PointerRNA tar_ptr;
+ if (dtar2->id && GS(dtar2->id->name) == ID_OB && ob2->pose) {
+ PointerRNA tar_ptr;
- RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr);
- uiItemPointerR(col, &dtar2_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
- }
+ RNA_pointer_create(dtar2->id, &RNA_Pose, ob2->pose, &tar_ptr);
+ uiItemPointerR(
+ col, &dtar2_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
+ }
- /* we can clear it again now - it's only needed when creating the ID/Bone fields */
- uiLayoutSetRedAlert(col, false);
+ /* we can clear it again now - it's only needed when creating the ID/Bone fields */
+ uiLayoutSetRedAlert(col, false);
- uiItemR(col, &dtar2_ptr, "transform_space", 0, NULL, ICON_NONE);
+ uiItemR(col, &dtar2_ptr, "transform_space", 0, NULL, ICON_NONE);
}
/* settings for 'transform channel' driver variable type */
static void graph_panel_driverVar__transChan(uiLayout *layout, ID *id, DriverVar *dvar)
{
- DriverTarget *dtar = &dvar->targets[0];
- Object *ob = (Object *)dtar->id;
- PointerRNA dtar_ptr;
- uiLayout *col, *sub;
-
- /* initialize RNA pointer to the target */
- RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
-
- /* properties */
- col = uiLayoutColumn(layout, true);
- uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
- uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object"), ICON_NONE);
-
- if (dtar->id && GS(dtar->id->name) == ID_OB && ob->pose) {
- PointerRNA tar_ptr;
-
- RNA_pointer_create(dtar->id, &RNA_Pose, ob->pose, &tar_ptr);
- uiItemPointerR(col, &dtar_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
- }
-
- sub = uiLayoutColumn(layout, true);
- uiItemR(sub, &dtar_ptr, "transform_type", 0, NULL, ICON_NONE);
- uiItemR(sub, &dtar_ptr, "transform_space", 0, IFACE_("Space"), ICON_NONE);
+ DriverTarget *dtar = &dvar->targets[0];
+ Object *ob = (Object *)dtar->id;
+ PointerRNA dtar_ptr;
+ uiLayout *col, *sub;
+
+ /* initialize RNA pointer to the target */
+ RNA_pointer_create(id, &RNA_DriverTarget, dtar, &dtar_ptr);
+
+ /* properties */
+ col = uiLayoutColumn(layout, true);
+ uiLayoutSetRedAlert(col, (dtar->flag & DTAR_FLAG_INVALID)); /* XXX: per field... */
+ uiItemR(col, &dtar_ptr, "id", 0, IFACE_("Object"), ICON_NONE);
+
+ if (dtar->id && GS(dtar->id->name) == ID_OB && ob->pose) {
+ PointerRNA tar_ptr;
+
+ RNA_pointer_create(dtar->id, &RNA_Pose, ob->pose, &tar_ptr);
+ uiItemPointerR(
+ col, &dtar_ptr, "bone_target", &tar_ptr, "bones", IFACE_("Bone"), ICON_BONE_DATA);
+ }
+
+ sub = uiLayoutColumn(layout, true);
+ uiItemR(sub, &dtar_ptr, "transform_type", 0, NULL, ICON_NONE);
+ uiItemR(sub, &dtar_ptr, "transform_space", 0, IFACE_("Space"), ICON_NONE);
}
/* ----------------------------------------------------------------- */
-
/* property driven by the driver - duplicates Active FCurve, but useful for clarity */
static void graph_draw_driven_property_panel(uiLayout *layout, ID *id, FCurve *fcu)
{
- PointerRNA fcu_ptr;
- uiLayout *row;
- char name[256];
- int icon = 0;
+ PointerRNA fcu_ptr;
+ uiLayout *row;
+ char name[256];
+ int icon = 0;
- /* F-Curve pointer */
- RNA_pointer_create(id, &RNA_FCurve, fcu, &fcu_ptr);
+ /* F-Curve pointer */
+ RNA_pointer_create(id, &RNA_FCurve, fcu, &fcu_ptr);
- /* get user-friendly 'name' for F-Curve */
- icon = getname_anim_fcurve(name, id, fcu);
+ /* get user-friendly 'name' for F-Curve */
+ icon = getname_anim_fcurve(name, id, fcu);
- /* panel layout... */
- row = uiLayoutRow(layout, true);
- uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
+ /* panel layout... */
+ row = uiLayoutRow(layout, true);
+ uiLayoutSetAlignment(row, UI_LAYOUT_ALIGN_LEFT);
- /* -> user friendly 'name' for datablock that owns F-Curve */
- /* XXX: Actually, we may need the datablock icons only... (e.g. right now will show bone for bone props) */
- uiItemL(row, id->name + 2, icon);
+ /* -> user friendly 'name' for datablock that owns F-Curve */
+ /* XXX: Actually, we may need the datablock icons only... (e.g. right now will show bone for bone props) */
+ uiItemL(row, id->name + 2, icon);
- /* -> user friendly 'name' for F-Curve/driver target */
- uiItemL(row, "", ICON_SMALL_TRI_RIGHT_VEC);
- uiItemL(row, name, ICON_RNA);
+ /* -> user friendly 'name' for F-Curve/driver target */
+ uiItemL(row, "", ICON_SMALL_TRI_RIGHT_VEC);
+ uiItemL(row, name, ICON_RNA);
}
/* UI properties panel layout for driver settings - shared for Drivers Editor and for */
-static void graph_draw_driver_settings_panel(uiLayout *layout, ID *id, FCurve *fcu, const bool is_popover)
+static void graph_draw_driver_settings_panel(uiLayout *layout,
+ ID *id,
+ FCurve *fcu,
+ const bool is_popover)
{
- ChannelDriver *driver = fcu->driver;
- DriverVar *dvar;
-
- PointerRNA driver_ptr;
- uiLayout *col, *row;
- uiBlock *block;
- uiBut *but;
-
- /* set event handler for panel */
- block = uiLayoutGetBlock(layout);
- UI_block_func_handle_set(block, do_graph_region_driver_buttons, id);
-
- /* driver-level settings - type, expressions, and errors */
- RNA_pointer_create(id, &RNA_Driver, driver, &driver_ptr);
-
- col = uiLayoutColumn(layout, true);
- block = uiLayoutGetBlock(col);
- uiItemR(col, &driver_ptr, "type", 0, NULL, ICON_NONE);
-
- {
- char valBuf[32];
-
- /* value of driver */
- row = uiLayoutRow(col, true);
- uiItemL(row, IFACE_("Driver Value:"), ICON_NONE);
- BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", driver->curval);
- uiItemL(row, valBuf, ICON_NONE);
- }
-
- uiItemS(layout);
- uiItemS(layout);
-
- /* show expression box if doing scripted drivers, and/or error messages when invalid drivers exist */
- if (driver->type == DRIVER_TYPE_PYTHON) {
- bool bpy_data_expr_error = (strstr(driver->expression, "bpy.data.") != NULL);
- bool bpy_ctx_expr_error = (strstr(driver->expression, "bpy.context.") != NULL);
-
- /* expression */
- /* TODO: "Show syntax hints" button */
- col = uiLayoutColumn(layout, true);
- block = uiLayoutGetBlock(col);
-
- uiItemL(col, IFACE_("Expression:"), ICON_NONE);
- uiItemR(col, &driver_ptr, "expression", 0, "", ICON_NONE);
- uiItemR(col, &driver_ptr, "use_self", 0, NULL, ICON_NONE);
-
- /* errors? */
- col = uiLayoutColumn(layout, true);
- block = uiLayoutGetBlock(col);
-
- if (driver->flag & DRIVER_FLAG_INVALID) {
- uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_CANCEL);
- }
- else if (!BKE_driver_has_simple_expression(driver)) {
- if ((G.f & G_FLAG_SCRIPT_AUTOEXEC) == 0) {
- /* TODO: Add button to enable? */
- uiItemL(col, IFACE_("WARNING: Python expressions limited for security"), ICON_ERROR);
- }
- else {
- uiItemL(col, IFACE_("Slow Python expression"), ICON_INFO);
- }
- }
-
- /* Explicit bpy-references are evil. Warn about these to prevent errors */
- /* TODO: put these in a box? */
- if (bpy_data_expr_error || bpy_ctx_expr_error) {
- uiItemL(col, IFACE_("WARNING: Driver expression may not work correctly"), ICON_HELP);
-
- if (bpy_data_expr_error) {
- uiItemL(col, IFACE_("TIP: Use variables instead of bpy.data paths (see below)"), ICON_ERROR);
- }
- if (bpy_ctx_expr_error) {
- uiItemL(col, IFACE_("TIP: bpy.context is not safe for renderfarm usage"), ICON_ERROR);
- }
- }
- }
- else {
- /* errors? */
- col = uiLayoutColumn(layout, true);
- block = uiLayoutGetBlock(col);
-
- if (driver->flag & DRIVER_FLAG_INVALID)
- uiItemL(col, IFACE_("ERROR: Invalid target channel(s)"), ICON_ERROR);
-
- /* Warnings about a lack of variables
- * NOTE: The lack of variables is generally a bad thing, since it indicates
- * that the driver doesn't work at all. This particular scenario arises
- * primarily when users mistakenly try to use drivers for procedural
- * property animation
- */
- if (BLI_listbase_is_empty(&driver->variables)) {
- uiItemL(col, IFACE_("ERROR: Driver is useless without any inputs"), ICON_ERROR);
-
- if (!BLI_listbase_is_empty(&fcu->modifiers)) {
- uiItemL(col, IFACE_("TIP: Use F-Curves for procedural animation instead"), ICON_INFO);
- uiItemL(col, IFACE_("F-Modifiers can generate curves for those too"), ICON_INFO);
- }
- }
- }
-
- uiItemS(layout);
-
- /* add/copy/paste driver variables */
- if (is_popover) {
- /* add driver variable - add blank */
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
- but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ADD, IFACE_("Add Input Variable"),
- 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, 0,
- TIP_("Add a Driver Variable to keep track an input used by the driver"));
- UI_but_func_set(but, driver_add_var_cb, driver, NULL);
-
- /* add driver variable - add using eyedropper */
- /* XXX: will this operator work like this? */
- uiItemO(row, "", ICON_EYEDROPPER, "UI_OT_eyedropper_driver");
- }
- else {
- /* add driver variable */
- row = uiLayoutRow(layout, false);
- block = uiLayoutGetBlock(row);
- but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ADD, IFACE_("Add Input Variable"),
- 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, 0,
- TIP_("Driver variables ensure that all dependencies will be accounted for, ensuring that drivers will update correctly"));
- UI_but_func_set(but, driver_add_var_cb, driver, NULL);
-
- /* copy/paste (as sub-row) */
- row = uiLayoutRow(row, true);
- block = uiLayoutGetBlock(row);
-
- uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_driver_variables_copy");
- uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_driver_variables_paste");
- }
-
- /* loop over targets, drawing them */
- for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
- PointerRNA dvar_ptr;
- uiLayout *box;
- uiLayout *subrow, *sub;
-
- /* sub-layout column for this variable's settings */
- col = uiLayoutColumn(layout, true);
-
- /* 1) header panel */
- box = uiLayoutBox(col);
- RNA_pointer_create(id, &RNA_DriverVariable, dvar, &dvar_ptr);
-
- row = uiLayoutRow(box, false);
- block = uiLayoutGetBlock(row);
-
- /* 1.1) variable type and name */
- subrow = uiLayoutRow(row, true);
-
- /* 1.1.1) variable type */
-
- /* HACK: special group just for the enum,
- * otherwise we get ugly layout with text included too... */
- sub = uiLayoutRow(subrow, true);
-
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
-
- uiItemR(sub, &dvar_ptr, "type", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
-
- /* 1.1.2) variable name */
-
- /* HACK: special group to counteract the effects of the previous enum,
- * which now pushes everything too far right */
- sub = uiLayoutRow(subrow, true);
-
- uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_EXPAND);
-
- uiItemR(sub, &dvar_ptr, "name", 0, "", ICON_NONE);
-
- /* 1.2) invalid name? */
- UI_block_emboss_set(block, UI_EMBOSS_NONE);
-
- if (dvar->flag & DVAR_FLAG_INVALID_NAME) {
- but = uiDefIconBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_ERROR, 290, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Invalid variable name, click here for details"));
- UI_but_func_set(but, driver_dvar_invalid_name_query_cb, dvar, NULL); // XXX: reports?
- }
-
- /* 1.3) remove button */
- but = uiDefIconBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_X, 290, 0, UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0.0, 0.0, IFACE_("Delete target variable"));
- UI_but_func_set(but, driver_delete_var_cb, driver, dvar);
- UI_block_emboss_set(block, UI_EMBOSS);
-
-
- /* 2) variable type settings */
- box = uiLayoutBox(col);
- /* controls to draw depends on the type of variable */
- switch (dvar->type) {
- case DVAR_TYPE_SINGLE_PROP: /* single property */
- graph_panel_driverVar__singleProp(box, id, dvar);
- break;
- case DVAR_TYPE_ROT_DIFF: /* rotational difference */
- graph_panel_driverVar__rotDiff(box, id, dvar);
- break;
- case DVAR_TYPE_LOC_DIFF: /* location difference */
- graph_panel_driverVar__locDiff(box, id, dvar);
- break;
- case DVAR_TYPE_TRANSFORM_CHAN: /* transform channel */
- graph_panel_driverVar__transChan(box, id, dvar);
- break;
- }
-
- /* 3) value of variable */
- {
- char valBuf[32];
-
- box = uiLayoutBox(col);
- row = uiLayoutRow(box, true);
- uiItemL(row, IFACE_("Value:"), ICON_NONE);
-
- if ((dvar->type == DVAR_TYPE_ROT_DIFF) ||
- (dvar->type == DVAR_TYPE_TRANSFORM_CHAN &&
- dvar->targets[0].transChan >= DTAR_TRANSCHAN_ROTX &&
- dvar->targets[0].transChan < DTAR_TRANSCHAN_SCALEX))
- {
- BLI_snprintf(valBuf, sizeof(valBuf), "%.3f (%4.1f°)", dvar->curval, RAD2DEGF(dvar->curval));
- }
- else {
- BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval);
- }
-
- uiItemL(row, valBuf, ICON_NONE);
- }
- }
-
- uiItemS(layout);
- uiItemS(layout);
-
- /* XXX: This should become redundant. But sometimes the flushing fails,
- * so keep this around for a while longer as a "last resort" */
- row = uiLayoutRow(layout, true);
- block = uiLayoutGetBlock(row);
- but = uiDefIconTextBut(block, UI_BTYPE_BUT, B_IPO_DEPCHANGE, ICON_FILE_REFRESH, IFACE_("Update Dependencies"),
- 0, 0, 10 * UI_UNIT_X, UI_UNIT_Y,
- NULL, 0.0, 0.0, 0, 0,
- TIP_("Force updates of dependencies - Only use this if drivers are not updating correctly"));
- UI_but_func_set(but, driver_update_flags_cb, fcu, NULL);
+ ChannelDriver *driver = fcu->driver;
+ DriverVar *dvar;
+
+ PointerRNA driver_ptr;
+ uiLayout *col, *row;
+ uiBlock *block;
+ uiBut *but;
+
+ /* set event handler for panel */
+ block = uiLayoutGetBlock(layout);
+ UI_block_func_handle_set(block, do_graph_region_driver_buttons, id);
+
+ /* driver-level settings - type, expressions, and errors */
+ RNA_pointer_create(id, &RNA_Driver, driver, &driver_ptr);
+
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+ uiItemR(col, &driver_ptr, "type", 0, NULL, ICON_NONE);
+
+ {
+ char valBuf[32];
+
+ /* value of driver */
+ row = uiLayoutRow(col, true);
+ uiItemL(row, IFACE_("Driver Value:"), ICON_NONE);
+ BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", driver->curval);
+ uiItemL(row, valBuf, ICON_NONE);
+ }
+
+ uiItemS(layout);
+ uiItemS(layout);
+
+ /* show expression box if doing scripted drivers, and/or error messages when invalid drivers exist */
+ if (driver->type == DRIVER_TYPE_PYTHON) {
+ bool bpy_data_expr_error = (strstr(driver->expression, "bpy.data.") != NULL);
+ bool bpy_ctx_expr_error = (strstr(driver->expression, "bpy.context.") != NULL);
+
+ /* expression */
+ /* TODO: "Show syntax hints" button */
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
+ uiItemL(col, IFACE_("Expression:"), ICON_NONE);
+ uiItemR(col, &driver_ptr, "expression", 0, "", ICON_NONE);
+ uiItemR(col, &driver_ptr, "use_self", 0, NULL, ICON_NONE);
+
+ /* errors? */
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
+ if (driver->flag & DRIVER_FLAG_INVALID) {
+ uiItemL(col, IFACE_("ERROR: Invalid Python expression"), ICON_CANCEL);
+ }
+ else if (!BKE_driver_has_simple_expression(driver)) {
+ if ((G.f & G_FLAG_SCRIPT_AUTOEXEC) == 0) {
+ /* TODO: Add button to enable? */
+ uiItemL(col, IFACE_("WARNING: Python expressions limited for security"), ICON_ERROR);
+ }
+ else {
+ uiItemL(col, IFACE_("Slow Python expression"), ICON_INFO);
+ }
+ }
+
+ /* Explicit bpy-references are evil. Warn about these to prevent errors */
+ /* TODO: put these in a box? */
+ if (bpy_data_expr_error || bpy_ctx_expr_error) {
+ uiItemL(col, IFACE_("WARNING: Driver expression may not work correctly"), ICON_HELP);
+
+ if (bpy_data_expr_error) {
+ uiItemL(
+ col, IFACE_("TIP: Use variables instead of bpy.data paths (see below)"), ICON_ERROR);
+ }
+ if (bpy_ctx_expr_error) {
+ uiItemL(col, IFACE_("TIP: bpy.context is not safe for renderfarm usage"), ICON_ERROR);
+ }
+ }
+ }
+ else {
+ /* errors? */
+ col = uiLayoutColumn(layout, true);
+ block = uiLayoutGetBlock(col);
+
+ if (driver->flag & DRIVER_FLAG_INVALID)
+ uiItemL(col, IFACE_("ERROR: Invalid target channel(s)"), ICON_ERROR);
+
+ /* Warnings about a lack of variables
+ * NOTE: The lack of variables is generally a bad thing, since it indicates
+ * that the driver doesn't work at all. This particular scenario arises
+ * primarily when users mistakenly try to use drivers for procedural
+ * property animation
+ */
+ if (BLI_listbase_is_empty(&driver->variables)) {
+ uiItemL(col, IFACE_("ERROR: Driver is useless without any inputs"), ICON_ERROR);
+
+ if (!BLI_listbase_is_empty(&fcu->modifiers)) {
+ uiItemL(col, IFACE_("TIP: Use F-Curves for procedural animation instead"), ICON_INFO);
+ uiItemL(col, IFACE_("F-Modifiers can generate curves for those too"), ICON_INFO);
+ }
+ }
+ }
+
+ uiItemS(layout);
+
+ /* add/copy/paste driver variables */
+ if (is_popover) {
+ /* add driver variable - add blank */
+ row = uiLayoutRow(layout, true);
+ block = uiLayoutGetBlock(row);
+ but = uiDefIconTextBut(
+ block,
+ UI_BTYPE_BUT,
+ B_IPO_DEPCHANGE,
+ ICON_ADD,
+ IFACE_("Add Input Variable"),
+ 0,
+ 0,
+ 10 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ TIP_("Add a Driver Variable to keep track an input used by the driver"));
+ UI_but_func_set(but, driver_add_var_cb, driver, NULL);
+
+ /* add driver variable - add using eyedropper */
+ /* XXX: will this operator work like this? */
+ uiItemO(row, "", ICON_EYEDROPPER, "UI_OT_eyedropper_driver");
+ }
+ else {
+ /* add driver variable */
+ row = uiLayoutRow(layout, false);
+ block = uiLayoutGetBlock(row);
+ but = uiDefIconTextBut(block,
+ UI_BTYPE_BUT,
+ B_IPO_DEPCHANGE,
+ ICON_ADD,
+ IFACE_("Add Input Variable"),
+ 0,
+ 0,
+ 10 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ TIP_("Driver variables ensure that all dependencies will be accounted "
+ "for, ensuring that drivers will update correctly"));
+ UI_but_func_set(but, driver_add_var_cb, driver, NULL);
+
+ /* copy/paste (as sub-row) */
+ row = uiLayoutRow(row, true);
+ block = uiLayoutGetBlock(row);
+
+ uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_driver_variables_copy");
+ uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_driver_variables_paste");
+ }
+
+ /* loop over targets, drawing them */
+ for (dvar = driver->variables.first; dvar; dvar = dvar->next) {
+ PointerRNA dvar_ptr;
+ uiLayout *box;
+ uiLayout *subrow, *sub;
+
+ /* sub-layout column for this variable's settings */
+ col = uiLayoutColumn(layout, true);
+
+ /* 1) header panel */
+ box = uiLayoutBox(col);
+ RNA_pointer_create(id, &RNA_DriverVariable, dvar, &dvar_ptr);
+
+ row = uiLayoutRow(box, false);
+ block = uiLayoutGetBlock(row);
+
+ /* 1.1) variable type and name */
+ subrow = uiLayoutRow(row, true);
+
+ /* 1.1.1) variable type */
+
+ /* HACK: special group just for the enum,
+ * otherwise we get ugly layout with text included too... */
+ sub = uiLayoutRow(subrow, true);
+
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_LEFT);
+
+ uiItemR(sub, &dvar_ptr, "type", UI_ITEM_R_ICON_ONLY, "", ICON_NONE);
+
+ /* 1.1.2) variable name */
+
+ /* HACK: special group to counteract the effects of the previous enum,
+ * which now pushes everything too far right */
+ sub = uiLayoutRow(subrow, true);
+
+ uiLayoutSetAlignment(sub, UI_LAYOUT_ALIGN_EXPAND);
+
+ uiItemR(sub, &dvar_ptr, "name", 0, "", ICON_NONE);
+
+ /* 1.2) invalid name? */
+ UI_block_emboss_set(block, UI_EMBOSS_NONE);
+
+ if (dvar->flag & DVAR_FLAG_INVALID_NAME) {
+ but = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ B_IPO_DEPCHANGE,
+ ICON_ERROR,
+ 290,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ IFACE_("Invalid variable name, click here for details"));
+ UI_but_func_set(but, driver_dvar_invalid_name_query_cb, dvar, NULL); // XXX: reports?
+ }
+
+ /* 1.3) remove button */
+ but = uiDefIconBut(block,
+ UI_BTYPE_BUT,
+ B_IPO_DEPCHANGE,
+ ICON_X,
+ 290,
+ 0,
+ UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ IFACE_("Delete target variable"));
+ UI_but_func_set(but, driver_delete_var_cb, driver, dvar);
+ UI_block_emboss_set(block, UI_EMBOSS);
+
+ /* 2) variable type settings */
+ box = uiLayoutBox(col);
+ /* controls to draw depends on the type of variable */
+ switch (dvar->type) {
+ case DVAR_TYPE_SINGLE_PROP: /* single property */
+ graph_panel_driverVar__singleProp(box, id, dvar);
+ break;
+ case DVAR_TYPE_ROT_DIFF: /* rotational difference */
+ graph_panel_driverVar__rotDiff(box, id, dvar);
+ break;
+ case DVAR_TYPE_LOC_DIFF: /* location difference */
+ graph_panel_driverVar__locDiff(box, id, dvar);
+ break;
+ case DVAR_TYPE_TRANSFORM_CHAN: /* transform channel */
+ graph_panel_driverVar__transChan(box, id, dvar);
+ break;
+ }
+
+ /* 3) value of variable */
+ {
+ char valBuf[32];
+
+ box = uiLayoutBox(col);
+ row = uiLayoutRow(box, true);
+ uiItemL(row, IFACE_("Value:"), ICON_NONE);
+
+ if ((dvar->type == DVAR_TYPE_ROT_DIFF) ||
+ (dvar->type == DVAR_TYPE_TRANSFORM_CHAN &&
+ dvar->targets[0].transChan >= DTAR_TRANSCHAN_ROTX &&
+ dvar->targets[0].transChan < DTAR_TRANSCHAN_SCALEX)) {
+ BLI_snprintf(
+ valBuf, sizeof(valBuf), "%.3f (%4.1f°)", dvar->curval, RAD2DEGF(dvar->curval));
+ }
+ else {
+ BLI_snprintf(valBuf, sizeof(valBuf), "%.3f", dvar->curval);
+ }
+
+ uiItemL(row, valBuf, ICON_NONE);
+ }
+ }
+
+ uiItemS(layout);
+ uiItemS(layout);
+
+ /* XXX: This should become redundant. But sometimes the flushing fails,
+ * so keep this around for a while longer as a "last resort" */
+ row = uiLayoutRow(layout, true);
+ block = uiLayoutGetBlock(row);
+ but = uiDefIconTextBut(
+ block,
+ UI_BTYPE_BUT,
+ B_IPO_DEPCHANGE,
+ ICON_FILE_REFRESH,
+ IFACE_("Update Dependencies"),
+ 0,
+ 0,
+ 10 * UI_UNIT_X,
+ UI_UNIT_Y,
+ NULL,
+ 0.0,
+ 0.0,
+ 0,
+ 0,
+ TIP_("Force updates of dependencies - Only use this if drivers are not updating correctly"));
+ UI_but_func_set(but, driver_update_flags_cb, fcu, NULL);
}
/* ----------------------------------------------------------------- */
-
/* panel to show property driven by the driver (in Drivers Editor) - duplicates Active FCurve, but useful for clarity */
static void graph_panel_driven_property(const bContext *C, Panel *pa)
{
- bAnimListElem *ale;
- FCurve *fcu;
+ bAnimListElem *ale;
+ FCurve *fcu;
- if (!graph_panel_context(C, &ale, &fcu))
- return;
+ if (!graph_panel_context(C, &ale, &fcu))
+ return;
- graph_draw_driven_property_panel(pa->layout, ale->id, fcu);
+ graph_draw_driven_property_panel(pa->layout, ale->id, fcu);
- MEM_freeN(ale);
+ MEM_freeN(ale);
}
/* driver settings for active F-Curve
* (only for 'Drivers' mode in Graph Editor, i.e. the full "Drivers Editor") */
static void graph_panel_drivers(const bContext *C, Panel *pa)
{
- bAnimListElem *ale;
- FCurve *fcu;
+ bAnimListElem *ale;
+ FCurve *fcu;
- /* Get settings from context */
- if (!graph_panel_context(C, &ale, &fcu))
- return;
+ /* Get settings from context */
+ if (!graph_panel_context(C, &ale, &fcu))
+ return;
- graph_draw_driver_settings_panel(pa->layout, ale->id, fcu, false);
+ graph_draw_driver_settings_panel(pa->layout, ale->id, fcu, false);
- /* cleanup */
- MEM_freeN(ale);
+ /* cleanup */
+ MEM_freeN(ale);
}
/* ----------------------------------------------------------------- */
@@ -1048,205 +1226,206 @@ static void graph_panel_drivers(const bContext *C, Panel *pa)
/* poll to make this not show up in the graph editor, as this is only to be used as a popup elsewhere */
static bool graph_panel_drivers_popover_poll(const bContext *C, PanelType *UNUSED(pt))
{
- return ED_operator_graphedit_active((bContext *)C) == false;
+ return ED_operator_graphedit_active((bContext *)C) == false;
}
/* popover panel for driver editing anywhere in ui */
static void graph_panel_drivers_popover(const bContext *C, Panel *pa)
{
- uiLayout *layout = pa->layout;
-
- PointerRNA ptr = {{NULL}};
- PropertyRNA *prop = NULL;
- int index = -1;
- uiBut *but = NULL;
-
- /* Get active property to show driver properties for */
- but = UI_context_active_but_prop_get((bContext *)C, &ptr, &prop, &index);
- if (but) {
- FCurve *fcu;
- bool driven, special;
-
- fcu = rna_get_fcurve_context_ui((bContext *)C,
- &ptr, prop, index,
- NULL, NULL, &driven, &special);
-
- /* Hack: Force all buttons in this panel to be able to know the driver button
- * this panel is getting spawned from, so that things like the "Open Drivers Editor"
- * button will work.
- */
- uiLayoutSetContextFromBut(layout, but);
-
- /* Populate Panel - With a combination of the contents of the Driven and Driver panels */
- if (fcu) {
- ID *id = ptr.id.data;
-
- /* Driven Property Settings */
- uiItemL(layout, IFACE_("Driven Property:"), ICON_NONE);
- graph_draw_driven_property_panel(pa->layout, id, fcu);
- /* TODO: All vs Single */
-
- uiItemS(layout);
- uiItemS(layout);
-
- /* Drivers Settings */
- uiItemL(layout, IFACE_("Driver Settings:"), ICON_NONE);
- graph_draw_driver_settings_panel(pa->layout, id, fcu, true);
- }
- }
-
- /* Show drivers editor is always visible */
- uiItemO(layout, IFACE_("Show in Drivers Editor"), ICON_DRIVER, "SCREEN_OT_drivers_editor_show");
+ uiLayout *layout = pa->layout;
+
+ PointerRNA ptr = {{NULL}};
+ PropertyRNA *prop = NULL;
+ int index = -1;
+ uiBut *but = NULL;
+
+ /* Get active property to show driver properties for */
+ but = UI_context_active_but_prop_get((bContext *)C, &ptr, &prop, &index);
+ if (but) {
+ FCurve *fcu;
+ bool driven, special;
+
+ fcu = rna_get_fcurve_context_ui(
+ (bContext *)C, &ptr, prop, index, NULL, NULL, &driven, &special);
+
+ /* Hack: Force all buttons in this panel to be able to know the driver button
+ * this panel is getting spawned from, so that things like the "Open Drivers Editor"
+ * button will work.
+ */
+ uiLayoutSetContextFromBut(layout, but);
+
+ /* Populate Panel - With a combination of the contents of the Driven and Driver panels */
+ if (fcu) {
+ ID *id = ptr.id.data;
+
+ /* Driven Property Settings */
+ uiItemL(layout, IFACE_("Driven Property:"), ICON_NONE);
+ graph_draw_driven_property_panel(pa->layout, id, fcu);
+ /* TODO: All vs Single */
+
+ uiItemS(layout);
+ uiItemS(layout);
+
+ /* Drivers Settings */
+ uiItemL(layout, IFACE_("Driver Settings:"), ICON_NONE);
+ graph_draw_driver_settings_panel(pa->layout, id, fcu, true);
+ }
+ }
+
+ /* Show drivers editor is always visible */
+ uiItemO(layout, IFACE_("Show in Drivers Editor"), ICON_DRIVER, "SCREEN_OT_drivers_editor_show");
}
/* ******************* F-Modifiers ******************************** */
/* All the drawing code is in editors/animation/fmodifier_ui.c */
-#define B_FMODIFIER_REDRAW 20
+#define B_FMODIFIER_REDRAW 20
static void do_graph_region_modifier_buttons(bContext *C, void *UNUSED(arg), int event)
{
- switch (event) {
- case B_FMODIFIER_REDRAW: // XXX this should send depsgraph updates too
- WM_event_add_notifier(C, NC_ANIMATION, NULL); // XXX need a notifier specially for F-Modifiers
- break;
- }
+ switch (event) {
+ case B_FMODIFIER_REDRAW: // XXX this should send depsgraph updates too
+ WM_event_add_notifier(
+ C, NC_ANIMATION, NULL); // XXX need a notifier specially for F-Modifiers
+ break;
+ }
}
static void graph_panel_modifiers(const bContext *C, Panel *pa)
{
- bAnimListElem *ale;
- FCurve *fcu;
- FModifier *fcm;
- uiLayout *col, *row;
- uiBlock *block;
- bool active;
-
- if (!graph_panel_context(C, &ale, &fcu))
- return;
-
- block = uiLayoutGetBlock(pa->layout);
- UI_block_func_handle_set(block, do_graph_region_modifier_buttons, NULL);
-
- /* 'add modifier' button at top of panel */
- {
- row = uiLayoutRow(pa->layout, false);
-
- /* this is an operator button which calls a 'add modifier' operator...
- * a menu might be nicer but would be tricky as we need some custom filtering
- */
- uiItemMenuEnumO(row, (bContext *)C, "GRAPH_OT_fmodifier_add", "type", IFACE_("Add Modifier"), ICON_NONE);
-
- /* copy/paste (as sub-row) */
- row = uiLayoutRow(row, true);
- uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_fmodifier_copy");
- uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_fmodifier_paste");
- }
-
- active = !(fcu->flag & FCURVE_MOD_OFF);
- /* draw each modifier */
- for (fcm = fcu->modifiers.first; fcm; fcm = fcm->next) {
- col = uiLayoutColumn(pa->layout, true);
- uiLayoutSetActive(col, active);
-
- ANIM_uiTemplate_fmodifier_draw(col, ale->fcurve_owner_id, &fcu->modifiers, fcm);
- }
-
- MEM_freeN(ale);
+ bAnimListElem *ale;
+ FCurve *fcu;
+ FModifier *fcm;
+ uiLayout *col, *row;
+ uiBlock *block;
+ bool active;
+
+ if (!graph_panel_context(C, &ale, &fcu))
+ return;
+
+ block = uiLayoutGetBlock(pa->layout);
+ UI_block_func_handle_set(block, do_graph_region_modifier_buttons, NULL);
+
+ /* 'add modifier' button at top of panel */
+ {
+ row = uiLayoutRow(pa->layout, false);
+
+ /* this is an operator button which calls a 'add modifier' operator...
+ * a menu might be nicer but would be tricky as we need some custom filtering
+ */
+ uiItemMenuEnumO(
+ row, (bContext *)C, "GRAPH_OT_fmodifier_add", "type", IFACE_("Add Modifier"), ICON_NONE);
+
+ /* copy/paste (as sub-row) */
+ row = uiLayoutRow(row, true);
+ uiItemO(row, "", ICON_COPYDOWN, "GRAPH_OT_fmodifier_copy");
+ uiItemO(row, "", ICON_PASTEDOWN, "GRAPH_OT_fmodifier_paste");
+ }
+
+ active = !(fcu->flag & FCURVE_MOD_OFF);
+ /* draw each modifier */
+ for (fcm = fcu->modifiers.first; fcm; fcm = fcm->next) {
+ col = uiLayoutColumn(pa->layout, true);
+ uiLayoutSetActive(col, active);
+
+ ANIM_uiTemplate_fmodifier_draw(col, ale->fcurve_owner_id, &fcu->modifiers, fcm);
+ }
+
+ MEM_freeN(ale);
}
/* ******************* general ******************************** */
void graph_buttons_register(ARegionType *art)
{
- PanelType *pt;
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel properties");
- strcpy(pt->idname, "GRAPH_PT_properties");
- strcpy(pt->label, N_("Active F-Curve"));
- strcpy(pt->category, "F-Curve");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_properties;
- pt->poll = graph_panel_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel properties");
- strcpy(pt->idname, "GRAPH_PT_key_properties");
- strcpy(pt->label, N_("Active Keyframe"));
- strcpy(pt->category, "F-Curve");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_key_properties;
- pt->poll = graph_panel_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers driven");
- strcpy(pt->idname, "GRAPH_PT_driven_property");
- strcpy(pt->label, N_("Driven Property"));
- strcpy(pt->category, "Drivers");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_driven_property;
- pt->poll = graph_panel_drivers_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers");
- strcpy(pt->idname, "GRAPH_PT_drivers");
- strcpy(pt->label, N_("Driver"));
- strcpy(pt->category, "Drivers");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_drivers;
- pt->poll = graph_panel_drivers_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers pover");
- strcpy(pt->idname, "GRAPH_PT_drivers_popover");
- strcpy(pt->label, N_("Add/Edit Driver"));
- strcpy(pt->category, "Drivers");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_drivers_popover;
- pt->poll = graph_panel_drivers_popover_poll;
- BLI_addtail(&art->paneltypes, pt);
- /* This panel isn't used in this region.
- * Add explicitly to global list (so popovers work). */
- WM_paneltype_add(pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel modifiers");
- strcpy(pt->idname, "GRAPH_PT_modifiers");
- strcpy(pt->label, N_("Modifiers"));
- strcpy(pt->category, "Modifiers");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_modifiers;
- pt->poll = graph_panel_poll;
- BLI_addtail(&art->paneltypes, pt);
-
- pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel view");
- strcpy(pt->idname, "GRAPH_PT_view");
- strcpy(pt->label, N_("View Properties"));
- strcpy(pt->category, "View");
- strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
- pt->draw = graph_panel_view;
- BLI_addtail(&art->paneltypes, pt);
+ PanelType *pt;
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel properties");
+ strcpy(pt->idname, "GRAPH_PT_properties");
+ strcpy(pt->label, N_("Active F-Curve"));
+ strcpy(pt->category, "F-Curve");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_properties;
+ pt->poll = graph_panel_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel properties");
+ strcpy(pt->idname, "GRAPH_PT_key_properties");
+ strcpy(pt->label, N_("Active Keyframe"));
+ strcpy(pt->category, "F-Curve");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_key_properties;
+ pt->poll = graph_panel_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers driven");
+ strcpy(pt->idname, "GRAPH_PT_driven_property");
+ strcpy(pt->label, N_("Driven Property"));
+ strcpy(pt->category, "Drivers");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_driven_property;
+ pt->poll = graph_panel_drivers_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers");
+ strcpy(pt->idname, "GRAPH_PT_drivers");
+ strcpy(pt->label, N_("Driver"));
+ strcpy(pt->category, "Drivers");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_drivers;
+ pt->poll = graph_panel_drivers_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel drivers pover");
+ strcpy(pt->idname, "GRAPH_PT_drivers_popover");
+ strcpy(pt->label, N_("Add/Edit Driver"));
+ strcpy(pt->category, "Drivers");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_drivers_popover;
+ pt->poll = graph_panel_drivers_popover_poll;
+ BLI_addtail(&art->paneltypes, pt);
+ /* This panel isn't used in this region.
+ * Add explicitly to global list (so popovers work). */
+ WM_paneltype_add(pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel modifiers");
+ strcpy(pt->idname, "GRAPH_PT_modifiers");
+ strcpy(pt->label, N_("Modifiers"));
+ strcpy(pt->category, "Modifiers");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_modifiers;
+ pt->poll = graph_panel_poll;
+ BLI_addtail(&art->paneltypes, pt);
+
+ pt = MEM_callocN(sizeof(PanelType), "spacetype graph panel view");
+ strcpy(pt->idname, "GRAPH_PT_view");
+ strcpy(pt->label, N_("View Properties"));
+ strcpy(pt->category, "View");
+ strcpy(pt->translation_context, BLT_I18NCONTEXT_DEFAULT_BPYRNA);
+ pt->draw = graph_panel_view;
+ BLI_addtail(&art->paneltypes, pt);
}
static int graph_properties_toggle_exec(bContext *C, wmOperator *UNUSED(op))
{
- ScrArea *sa = CTX_wm_area(C);
- ARegion *ar = graph_has_buttons_region(sa);
+ ScrArea *sa = CTX_wm_area(C);
+ ARegion *ar = graph_has_buttons_region(sa);
- if (ar)
- ED_region_toggle_hidden(C, ar);
+ if (ar)
+ ED_region_toggle_hidden(C, ar);
- return OPERATOR_FINISHED;
+ return OPERATOR_FINISHED;
}
void GRAPH_OT_properties(wmOperatorType *ot)
{
- ot->name = "Toggle Sidebar";
- ot->idname = "GRAPH_OT_properties";
- ot->description = "Toggle the properties region visibility";
+ ot->name = "Toggle Sidebar";
+ ot->idname = "GRAPH_OT_properties";
+ ot->description = "Toggle the properties region visibility";
- ot->exec = graph_properties_toggle_exec;
- ot->poll = ED_operator_graphedit_active;
+ ot->exec = graph_properties_toggle_exec;
+ ot->poll = ED_operator_graphedit_active;
- /* flags */
- ot->flag = 0;
+ /* flags */
+ ot->flag = 0;
}