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:
-rw-r--r--source/blender/editors/animation/drivers.c227
-rw-r--r--source/blender/editors/include/ED_keyframing.h35
-rw-r--r--source/blender/editors/interface/interface_eyedropper.c195
-rw-r--r--source/blender/editors/interface/interface_handlers.c3
-rw-r--r--source/blender/editors/interface/interface_intern.h2
-rw-r--r--source/blender/editors/interface/interface_ops.c1
6 files changed, 440 insertions, 23 deletions
diff --git a/source/blender/editors/animation/drivers.c b/source/blender/editors/animation/drivers.c
index 1f77ddc73b1..65a235e88f6 100644
--- a/source/blender/editors/animation/drivers.c
+++ b/source/blender/editors/animation/drivers.c
@@ -37,6 +37,7 @@
#include "BLI_blenlib.h"
#include "BLI_utildefines.h"
+#include "BLI_string.h"
#include "DNA_anim_types.h"
#include "DNA_texture_types.h"
@@ -154,6 +155,198 @@ FCurve *verify_driver_fcurve(ID *id, const char rna_path[], const int array_inde
/* ************************************************** */
/* Driver Management API */
+/* Mapping Types enum for operators */
+// XXX: These names need reviewing
+EnumPropertyItem prop_driver_create_mapping_types[] = {
+ {CREATEDRIVER_MAPPING_1_N, "SINGLE_MANY", 0, "Single Target, Multiple Properties",
+ "Use the picked item to drive all components of this property"},
+ {CREATEDRIVER_MAPPING_1_1, "DIRECT", 0, "Single Item Only",
+ "Use picked item to drive property under mouse"},
+ {CREATEDRIVER_MAPPING_N_N, "MATCH", 0, "Match Indices",
+ "Create drivers for each pair of corresponding elements"},
+ {0, NULL, 0, NULL, NULL}
+};
+
+/* --------------------------------- */
+
+/* Helper for ANIM_add_driver_with_target - Adds the actual driver */
+static int add_driver_with_target(
+ ReportList *reports,
+ ID *dst_id, const char dst_path[], int dst_index,
+ ID *src_id, const char src_path[], int src_index,
+ PointerRNA *src_ptr, PropertyRNA *src_prop,
+ short flag, int driver_type)
+{
+ FCurve *fcu;
+ short add_mode = (flag & CREATEDRIVER_WITH_FMODIFIER) ? 2 : 1;
+ const char *prop_name = RNA_property_identifier(src_prop);
+
+ /* Create F-Curve with Driver */
+ fcu = verify_driver_fcurve(dst_id, dst_path, dst_index, add_mode);
+
+ if (fcu && fcu->driver) {
+ ChannelDriver *driver = fcu->driver;
+ DriverVar *dvar;
+
+ /* Set the type of the driver */
+ driver->type = driver_type;
+ BLI_strncpy(driver->expression, "var", sizeof(driver->expression)); /* XXX: if we have N-1 mapping, we need to include all those here... */
+
+ /* Create a driver variable for the target
+ * - For transform properties, we want to automatically use "transform channel" instead
+ * (The only issue is with quat rotations vs euler channels...)
+ */
+ dvar = driver_add_new_variable(driver);
+
+ if (ELEM(src_ptr->type, &RNA_Object, &RNA_PoseBone) &&
+ (STREQ(prop_name, "location") || STREQ(prop_name, "scale") || strstr(prop_name, "rotation_")))
+ {
+ /* Transform Channel */
+ DriverTarget *dtar;
+
+ driver_change_variable_type(dvar, DVAR_TYPE_TRANSFORM_CHAN);
+ dtar = &dvar->targets[0];
+
+ /* Bone or Object target? */
+ dtar->id = src_id;
+ dtar->idtype = GS(src_id->name);
+
+ if (src_ptr->type == &RNA_PoseBone) {
+ RNA_string_get(src_ptr, "name", dtar->pchan_name);
+ }
+
+ /* Transform channel depends on type */
+ if (STREQ(prop_name, "location")) {
+ if (src_index == 2)
+ dtar->transChan = DTAR_TRANSCHAN_LOCZ;
+ else if (src_index == 1)
+ dtar->transChan = DTAR_TRANSCHAN_LOCY;
+ else
+ dtar->transChan = DTAR_TRANSCHAN_LOCX;
+ }
+ else if (STREQ(prop_name, "scale")) {
+ if (src_index == 2)
+ dtar->transChan = DTAR_TRANSCHAN_SCALEZ;
+ else if (src_index == 1)
+ dtar->transChan = DTAR_TRANSCHAN_SCALEY;
+ else
+ dtar->transChan = DTAR_TRANSCHAN_SCALEX;
+ }
+ else {
+ /* XXX: With quaternions and axis-angle, this mapping might not be correct...
+ * But since those have 4 elements instead, there's not much we can do
+ */
+ if (src_index == 2)
+ dtar->transChan = DTAR_TRANSCHAN_ROTZ;
+ else if (src_index == 1)
+ dtar->transChan = DTAR_TRANSCHAN_ROTY;
+ else
+ dtar->transChan = DTAR_TRANSCHAN_ROTX;
+ }
+ }
+ else {
+ /* Single RNA Property */
+ DriverTarget *dtar = &dvar->targets[0];
+
+ /* ID is as-is */
+ dtar->id = src_id;
+ dtar->idtype = GS(src_id->name);
+
+ /* Need to make a copy of the path (or build one with array index built in) */
+ if (RNA_property_array_check(src_prop)) {
+ dtar->rna_path = BLI_sprintfN("%s[%d]", src_path, src_index);
+ }
+ else {
+ dtar->rna_path = BLI_strdup(src_path);
+ }
+ }
+ }
+
+ /* set the done status */
+ return (fcu != NULL);
+}
+
+/* Main Driver Management API calls:
+ * Add a new driver for the specified property on the given ID block,
+ * and make it be driven by the specified target.
+ *
+ * This is intended to be used in conjunction with a modal "eyedropper"
+ * for picking the variable that is going to be used to drive this one.
+ *
+ * - flag: eCreateDriverFlags
+ * - driver_type: eDriver_Types
+ * - mapping_type: eCreateDriver_MappingTypes
+ */
+int ANIM_add_driver_with_target(
+ ReportList *reports,
+ ID *dst_id, const char dst_path[], int dst_index,
+ ID *src_id, const char src_path[], int src_index,
+ short flag, int driver_type, short mapping_type)
+{
+ PointerRNA id_ptr, ptr;
+ PropertyRNA *prop;
+
+ PointerRNA id_ptr2, ptr2;
+ PropertyRNA *prop2;
+ int done_tot = 0;
+
+ /* validate pointers first - exit if failure */
+ RNA_id_pointer_create(dst_id, &id_ptr);
+ if (RNA_path_resolve_property(&id_ptr, dst_path, &ptr, &prop) == false) {
+ BKE_reportf(reports, RPT_ERROR,
+ "Could not add driver, as RNA path is invalid for the given ID (ID = %s, path = %s)",
+ dst_id->name, dst_path);
+ return 0;
+ }
+
+ RNA_id_pointer_create(src_id, &id_ptr2);
+ if (RNA_path_resolve_property(&id_ptr2, src_path, &ptr2, &prop2) == false) {
+ /* No target - So, fall back to default method for adding a "simple" driver normally */
+ return ANIM_add_driver(reports, dst_id, dst_path, dst_index, flag, driver_type);
+ }
+
+ /* handle curve-property mappings based on mapping_type */
+ switch (mapping_type) {
+ case CREATEDRIVER_MAPPING_N_N: /* N-N - Try to match as much as possible, then use the first one */
+ {
+ /* Use the shorter of the two (to avoid out of bounds access) */
+ int dst_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
+ int src_len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr2, prop2) : 1;
+
+ int len = MIN2(dst_len, src_len);
+ int i;
+
+ for (i = 0; i < len; i++) {
+ done_tot += add_driver_with_target(reports, dst_id, dst_path, i, src_id, src_path, i, &ptr2, prop2, flag, driver_type);
+ }
+ break;
+ }
+
+ case CREATEDRIVER_MAPPING_1_N: /* 1-N - Specified target index for all */
+ default:
+ {
+ int len = (RNA_property_array_check(prop)) ? RNA_property_array_length(&ptr, prop) : 1;
+ int i;
+
+ for (i = 0; i < len; i++) {
+ done_tot += add_driver_with_target(reports, dst_id, dst_path, i, src_id, src_path, src_index, &ptr2, prop2, flag, driver_type);
+ }
+ break;
+ }
+
+ case CREATEDRIVER_MAPPING_1_1: /* 1-1 - Use the specified index (unless -1) */
+ {
+ done_tot = add_driver_with_target(reports, dst_id, dst_path, dst_index, src_id, src_path, src_index, &ptr2, prop2, flag, driver_type);
+ break;
+ }
+ }
+
+ /* done */
+ return done_tot;
+}
+
+/* --------------------------------- */
+
/* Main Driver Management API calls:
* Add a new driver for the specified property on the given ID block
*/
@@ -427,35 +620,31 @@ static int add_driver_button_exec(bContext *C, wmOperator *op)
{
PointerRNA ptr = {{NULL}};
PropertyRNA *prop = NULL;
- int success = 0;
int index;
+
const bool all = RNA_boolean_get(op->ptr, "all");
+ int ret = OPERATOR_CANCELLED;
/* try to create driver using property retrieved from UI */
UI_context_active_but_prop_get(C, &ptr, &prop, &index);
- if (all)
- index = -1;
-
if (ptr.id.data && ptr.data && prop && RNA_property_animateable(&ptr, prop)) {
- char *path = BKE_animdata_driver_path_hack(C, &ptr, prop, NULL);
- short flags = CREATEDRIVER_WITH_DEFAULT_DVAR;
+ wmOperatorType *ot = WM_operatortype_find("UI_OT_eyedropper_driver", true);
+ PointerRNA op_ptr;
- if (path) {
- success += ANIM_add_driver(op->reports, ptr.id.data, path, index, flags, DRIVER_TYPE_PYTHON);
-
- MEM_freeN(path);
- }
- }
-
- if (success) {
- /* send updates */
- UI_context_update_anim_flag(C);
- DAG_relations_tag_update(CTX_data_main(C));
- WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
+ WM_operator_properties_create_ptr(&op_ptr, ot);
+
+ if (all)
+ RNA_enum_set(&op_ptr, "mapping_type", CREATEDRIVER_MAPPING_1_N);
+ else
+ RNA_enum_set(&op_ptr, "mapping_type", CREATEDRIVER_MAPPING_1_1);
+
+ ret = WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &op_ptr);
+
+ WM_operator_properties_free(&op_ptr);
}
- return (success) ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
+ return ret;
}
void ANIM_OT_driver_button_add(wmOperatorType *ot)
diff --git a/source/blender/editors/include/ED_keyframing.h b/source/blender/editors/include/ED_keyframing.h
index 02b22bdbf42..eb21a431702 100644
--- a/source/blender/editors/include/ED_keyframing.h
+++ b/source/blender/editors/include/ED_keyframing.h
@@ -235,6 +235,16 @@ typedef enum eCreateDriverFlags {
CREATEDRIVER_WITH_FMODIFIER = (1 << 1), /* create drivers with Generator FModifier (for backwards compat) */
} eCreateDriverFlags;
+/* Heuristic to use for connecting target properties to driven ones */
+typedef enum eCreateDriver_MappingTypes {
+ CREATEDRIVER_MAPPING_1_N = 0, /* 1 to Many - Use the specified index, and drive all elements with it */
+ CREATEDRIVER_MAPPING_1_1 = 1, /* 1 to 1 - Only for the specified index on each side */
+ CREATEDRIVER_MAPPING_N_N = 2, /* Many to Many - Match up the indices one by one (only for drivers on vectors/arrays) */
+} eCreateDriver_MappingTypes;
+
+/* RNA Enum of eCreateDriver_MappingTypes, for use by the appropriate operators */
+extern EnumPropertyItem prop_driver_create_mapping_types[];
+
/* -------- */
/* Low-level call to add a new driver F-Curve. This shouldn't be used directly for most tools,
@@ -244,8 +254,24 @@ struct FCurve *verify_driver_fcurve(struct ID *id, const char rna_path[], const
/* -------- */
-/* Returns whether there is a driver in the copy/paste buffer to paste */
-bool ANIM_driver_can_paste(void);
+/* Main Driver Management API calls:
+ * Add a new driver for the specified property on the given ID block,
+ * and make it be driven by the specified target.
+ *
+ * This is intended to be used in conjunction with a modal "eyedropper"
+ * for picking the variable that is going to be used to drive this one.
+ *
+ * - flag: eCreateDriverFlags
+ * - driver_type: eDriver_Types
+ * - mapping_type: eCreateDriver_MappingTypes
+ */
+int ANIM_add_driver_with_target(
+ struct ReportList *reports,
+ struct ID *dst_id, const char dst_path[], int dst_index,
+ struct ID *src_id, const char src_path[], int src_index,
+ short flag, int driver_type, short mapping_type);
+
+/* -------- */
/* Main Driver Management API calls:
* Add a new driver for the specified property on the given ID block
@@ -257,6 +283,11 @@ int ANIM_add_driver(struct ReportList *reports, struct ID *id, const char rna_pa
*/
bool ANIM_remove_driver(struct ReportList *reports, struct ID *id, const char rna_path[], int array_index, short flag);
+/* -------- */
+
+/* Returns whether there is a driver in the copy/paste buffer to paste */
+bool ANIM_driver_can_paste(void);
+
/* Main Driver Management API calls:
* Make a copy of the driver for the specified property on the given ID block
*/
diff --git a/source/blender/editors/interface/interface_eyedropper.c b/source/blender/editors/interface/interface_eyedropper.c
index 41a04698756..5120a5e1bd7 100644
--- a/source/blender/editors/interface/interface_eyedropper.c
+++ b/source/blender/editors/interface/interface_eyedropper.c
@@ -29,6 +29,7 @@
#include "MEM_guardedalloc.h"
+#include "DNA_anim_types.h"
#include "DNA_space_types.h"
#include "DNA_screen_types.h"
#include "DNA_object_types.h"
@@ -41,10 +42,13 @@
#include "BKE_context.h"
#include "BKE_screen.h"
#include "BKE_report.h"
+#include "BKE_animsys.h"
+#include "BKE_depsgraph.h"
#include "BKE_idcode.h"
#include "BKE_unit.h"
#include "RNA_access.h"
+#include "RNA_define.h"
#include "BIF_gl.h"
@@ -67,6 +71,9 @@
#include "ED_screen.h"
#include "ED_view3d.h"
+/* for Driver eyedropper */
+#include "ED_keyframing.h"
+
/* -------------------------------------------------------------------- */
/* Keymap
@@ -112,6 +119,7 @@ wmKeyMap *eyedropper_modal_keymap(wmKeyConfig *keyconf)
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_color");
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_id");
WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_depth");
+ WM_modalkeymap_assign(keymap, "UI_OT_eyedropper_driver");
return keymap;
}
@@ -1026,3 +1034,190 @@ void UI_OT_eyedropper_depth(wmOperatorType *ot)
}
/** \} */
+
+/* -------------------------------------------------------------------- */
+/* Eyedropper
+ */
+
+/* NOTE: This is here (instead of in drivers.c) because we need access the button internals,
+ * which we cannot access outside of the interface module
+ */
+
+/** \name Eyedropper (Driver Target)
+ * \{ */
+
+typedef struct DriverDropper {
+ /* Destination property (i.e. where we'll add a driver) */
+ PointerRNA ptr;
+ PropertyRNA *prop;
+ int index;
+
+ // TODO: new target?
+} DriverDropper;
+
+static bool driverdropper_init(bContext *C, wmOperator *op)
+{
+ DriverDropper *ddr;
+ uiBut *but;
+
+ op->customdata = ddr = MEM_callocN(sizeof(DriverDropper), "DriverDropper");
+
+ UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &ddr->index);
+ but = UI_context_active_but_get(C);
+
+ if ((ddr->ptr.data == NULL) ||
+ (ddr->prop == NULL) ||
+ (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
+ (RNA_property_animateable(&ddr->ptr, ddr->prop) == false) ||
+ (but->flag & UI_BUT_DRIVEN))
+ {
+ return false;
+ }
+
+ return true;
+}
+
+static void driverdropper_exit(bContext *C, wmOperator *op)
+{
+ WM_cursor_modal_restore(CTX_wm_window(C));
+
+ if (op->customdata) {
+ MEM_freeN(op->customdata);
+ op->customdata = NULL;
+ }
+}
+
+static void driverdropper_sample(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ DriverDropper *ddr = (DriverDropper *)op->customdata;
+
+ wmWindow *win = CTX_wm_window(C);
+ ScrArea *sa = BKE_screen_find_area_xy(win->screen, SPACE_TYPE_ANY, event->x, event->y);
+ ARegion *ar = BKE_area_find_region_xy(sa, RGN_TYPE_ANY, event->x, event->y);
+
+ uiBut *but = ui_but_find_mouse_over(ar, event);
+
+ short mapping_type = RNA_enum_get(op->ptr, "mapping_type");
+ short flag = 0;
+
+ /* we can only add a driver if we know what RNA property it corresponds to */
+ if (ELEM(NULL, but, but->rnapoin.data, but->rnaprop)) {
+ return;
+ }
+ else {
+ /* Get paths for src... */
+ PointerRNA *target_ptr = &but->rnapoin;
+ PropertyRNA *target_prop = but->rnaprop;
+ int target_index = but->rnaindex;
+
+ char *target_path = RNA_path_from_ID_to_property(target_ptr, target_prop);
+
+ /* ... and destination */
+ char *dst_path = BKE_animdata_driver_path_hack(C, &ddr->ptr, ddr->prop, NULL);
+
+ /* Now create driver(s) */
+ int success = ANIM_add_driver_with_target(op->reports,
+ ddr->ptr.id.data, dst_path, ddr->index,
+ target_ptr->id.data, target_path, target_index,
+ flag, DRIVER_TYPE_PYTHON, mapping_type);
+
+ if (success) {
+ /* send updates */
+ UI_context_update_anim_flag(C);
+ DAG_relations_tag_update(CTX_data_main(C));
+ DAG_id_tag_update(ddr->ptr.id.data, OB_RECALC_OB | OB_RECALC_DATA);
+ WM_event_add_notifier(C, NC_ANIMATION | ND_FCURVES_ORDER, NULL); // XXX
+ }
+ }
+}
+
+static void driverdropper_cancel(bContext *C, wmOperator *op)
+{
+ driverdropper_exit(C, op);
+}
+
+/* main modal status check */
+static int driverdropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
+{
+ DriverDropper *ddr = (DriverDropper *)op->customdata;
+
+ /* handle modal keymap */
+ if (event->type == EVT_MODAL_MAP) {
+ switch (event->val) {
+ case EYE_MODAL_CANCEL:
+ driverdropper_cancel(C, op);
+ return OPERATOR_CANCELLED;
+
+ case EYE_MODAL_SAMPLE_CONFIRM:
+ driverdropper_sample(C, op, event);
+ driverdropper_exit(C, op);
+
+ return OPERATOR_FINISHED;
+ }
+ }
+
+ return OPERATOR_RUNNING_MODAL;
+}
+
+/* Modal Operator init */
+static int driverdropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
+{
+ /* init */
+ if (driverdropper_init(C, op)) {
+ WM_cursor_modal_set(CTX_wm_window(C), BC_EYEDROPPER_CURSOR);
+
+ /* add temp handler */
+ WM_event_add_modal_handler(C, op);
+
+ return OPERATOR_RUNNING_MODAL;
+ }
+ else {
+ driverdropper_exit(C, op);
+ return OPERATOR_CANCELLED;
+ }
+}
+
+/* Repeat operator */
+static int driverdropper_exec(bContext *C, wmOperator *op)
+{
+ /* init */
+ if (driverdropper_init(C, op)) {
+ /* cleanup */
+ driverdropper_exit(C, op);
+
+ return OPERATOR_FINISHED;
+ }
+ else {
+ return OPERATOR_CANCELLED;
+ }
+}
+
+static int driverdropper_poll(bContext *C)
+{
+ if (!CTX_wm_window(C)) return 0;
+ else return 1;
+}
+
+void UI_OT_eyedropper_driver(wmOperatorType *ot)
+{
+ /* identifiers */
+ ot->name = "Eyedropper Driver";
+ ot->idname = "UI_OT_eyedropper_driver";
+ ot->description = "Pick a property to use as a driver target";
+
+ /* api callbacks */
+ ot->invoke = driverdropper_invoke;
+ ot->modal = driverdropper_modal;
+ ot->cancel = driverdropper_cancel;
+ ot->exec = driverdropper_exec;
+ ot->poll = driverdropper_poll;
+
+ /* flags */
+ ot->flag = OPTYPE_BLOCKING | OPTYPE_INTERNAL;
+
+ /* properties */
+ RNA_def_enum(ot->srna, "mapping_type", prop_driver_create_mapping_types, 0,
+ "Mapping Type", "Method used to match target and driven properties");
+}
+
+/** \} */
diff --git a/source/blender/editors/interface/interface_handlers.c b/source/blender/editors/interface/interface_handlers.c
index 3e495615e07..83635822765 100644
--- a/source/blender/editors/interface/interface_handlers.c
+++ b/source/blender/editors/interface/interface_handlers.c
@@ -397,7 +397,6 @@ static bool ui_but_is_interactive(const uiBut *but, const bool labeledit);
static bool ui_but_contains_pt(uiBut *but, float mx, float my);
static bool ui_but_contains_point_px(ARegion *ar, uiBut *but, int x, int y);
static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, const bool labeledit);
-static uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event);
static void button_activate_init(bContext *C, ARegion *ar, uiBut *but, uiButtonActivateType type);
static void button_activate_state(bContext *C, uiBut *but, uiHandleButtonState state);
static void button_activate_exit(
@@ -7506,7 +7505,7 @@ static uiBut *ui_but_find_mouse_over_ex(ARegion *ar, const int x, const int y, c
return butover;
}
-static uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event)
+uiBut *ui_but_find_mouse_over(ARegion *ar, const wmEvent *event)
{
return ui_but_find_mouse_over_ex(ar, event->x, event->y, event->ctrl != 0);
}
diff --git a/source/blender/editors/interface/interface_intern.h b/source/blender/editors/interface/interface_intern.h
index 9f01ae4d618..f02aad1ff87 100644
--- a/source/blender/editors/interface/interface_intern.h
+++ b/source/blender/editors/interface/interface_intern.h
@@ -660,6 +660,7 @@ extern int ui_but_menu_direction(uiBut *but);
extern void ui_but_text_password_hide(char password_str[UI_MAX_DRAW_STR], uiBut *but, const bool restore);
extern uiBut *ui_but_find_select_in_enum(uiBut *but, int direction);
extern uiBut *ui_but_find_active_in_region(struct ARegion *ar);
+extern uiBut *ui_but_find_mouse_over(struct ARegion *ar, const struct wmEvent *event);
bool ui_but_is_editable(const uiBut *but);
bool ui_but_is_editable_as_text(const uiBut *but);
void ui_but_pie_dir_visual(RadialDirection dir, float vec[2]);
@@ -745,5 +746,6 @@ struct wmKeyMap *eyedropper_modal_keymap(struct wmKeyConfig *keyconf);
void UI_OT_eyedropper_color(struct wmOperatorType *ot);
void UI_OT_eyedropper_id(struct wmOperatorType *ot);
void UI_OT_eyedropper_depth(struct wmOperatorType *ot);
+void UI_OT_eyedropper_driver(struct wmOperatorType *ot);
#endif /* __INTERFACE_INTERN_H__ */
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c
index 356abe1a92c..bacae0a28c6 100644
--- a/source/blender/editors/interface/interface_ops.c
+++ b/source/blender/editors/interface/interface_ops.c
@@ -1107,6 +1107,7 @@ void ED_operatortypes_ui(void)
WM_operatortype_append(UI_OT_eyedropper_color);
WM_operatortype_append(UI_OT_eyedropper_id);
WM_operatortype_append(UI_OT_eyedropper_depth);
+ WM_operatortype_append(UI_OT_eyedropper_driver);
}
/**