Blender V5.0
eyedropper_driver.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2009 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
13
14#include "MEM_guardedalloc.h"
15
16#include "DNA_anim_types.h"
17#include "DNA_screen_types.h"
18
19#include "BKE_context.hh"
20
21#include "DEG_depsgraph.hh"
23
24#include "RNA_access.hh"
25#include "RNA_define.hh"
26#include "RNA_path.hh"
27
28#include "WM_api.hh"
29#include "WM_types.hh"
30
31#include "ED_keyframing.hh"
32
33#include "eyedropper_intern.hh"
34#include "interface_intern.hh"
35
37 /* Destination property (i.e. where we'll add a driver) */
39 PropertyRNA *prop = nullptr;
40 int index = 0;
41 bool is_undo = false;
42
43 /* TODO: new target? */
44};
45
47{
48 DriverDropper *ddr = MEM_new<DriverDropper>(__func__);
49
50 uiBut *but = UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &ddr->index);
51
52 if ((ddr->ptr.data == nullptr) || (ddr->prop == nullptr) ||
53 (RNA_property_driver_editable(&ddr->ptr, ddr->prop) == false) || (but->flag & UI_BUT_DRIVEN))
54 {
55 MEM_delete(ddr);
56 return false;
57 }
58 op->customdata = ddr;
59
61
62 return true;
63}
64
66{
68
69 if (op->customdata) {
70 DriverDropper *ddr = static_cast<DriverDropper *>(op->customdata);
71 op->customdata = nullptr;
72 MEM_delete(ddr);
73 }
74}
75
76static void driverdropper_sample(bContext *C, wmOperator *op, const wmEvent *event)
77{
78 DriverDropper *ddr = static_cast<DriverDropper *>(op->customdata);
80
81 const short mapping_type = RNA_enum_get(op->ptr, "mapping_type");
82 const short flag = 0;
83
84 /* we can only add a driver if we know what RNA property it corresponds to */
85 if (but == nullptr) {
86 return;
87 }
88 /* Get paths for the source. */
89 PointerRNA *target_ptr = &but->rnapoin;
90 PropertyRNA *target_prop = but->rnaprop;
91 const int target_index = but->rnaindex;
92
93 const std::optional<std::string> target_path = RNA_path_from_ID_to_property(target_ptr,
94 target_prop);
95
96 /* Get paths for the destination. */
97 const std::optional<std::string> dst_path = RNA_path_from_ID_to_property(&ddr->ptr, ddr->prop);
98
99 /* Now create driver(s) */
100 if (target_path && dst_path) {
101 int success = ANIM_add_driver_with_target(op->reports,
102 ddr->ptr.owner_id,
103 dst_path->c_str(),
104 ddr->index,
105 target_ptr->owner_id,
106 target_path->c_str(),
107 target_index,
108 flag,
110 mapping_type);
111
112 if (success) {
113 /* send updates */
118 }
119 }
120}
121
123{
125}
126
127/* main modal status check */
129{
130 DriverDropper *ddr = static_cast<DriverDropper *>(op->customdata);
131
132 /* handle modal keymap */
133 if (event->type == EVT_MODAL_MAP) {
134 switch (event->val) {
135 case EYE_MODAL_CANCEL: {
137 return OPERATOR_CANCELLED;
138 }
140 const bool is_undo = ddr->is_undo;
141 driverdropper_sample(C, op, event);
143 /* Could support finished & undo-skip. */
144 return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
145 }
146 }
147 }
148
150}
151
152/* Modal Operator init */
154 wmOperator *op,
155 const wmEvent * /*event*/)
156{
157 /* init */
158 if (driverdropper_init(C, op)) {
159 wmWindow *win = CTX_wm_window(C);
160 /* Workaround for de-activating the button clearing the cursor, see #76794 */
163
164 /* add temp handler */
166
168 }
169 return OPERATOR_CANCELLED;
170}
171
172/* Repeat operator */
174{
175 /* init */
176 if (driverdropper_init(C, op)) {
177 /* cleanup */
179
180 return OPERATOR_FINISHED;
181 }
182 return OPERATOR_CANCELLED;
183}
184
186{
187 if (!CTX_wm_window(C)) {
188 return false;
189 }
190 return true;
191}
192
194{
195 /* identifiers */
196 ot->name = "Eyedropper Driver";
197 ot->idname = "UI_OT_eyedropper_driver";
198 ot->description = "Pick a property to use as a driver target";
199
200 /* API callbacks. */
201 ot->invoke = driverdropper_invoke;
202 ot->modal = driverdropper_modal;
203 ot->cancel = driverdropper_cancel;
204 ot->exec = driverdropper_exec;
205 ot->poll = driverdropper_poll;
206
207 /* flags */
209
210 /* properties */
211 RNA_def_enum(ot->srna,
212 "mapping_type",
214 0,
215 "Mapping Type",
216 "Method used to match target and driven properties");
217}
wmWindow * CTX_wm_window(const bContext *C)
Main * CTX_data_main(const bContext *C)
ARegion * CTX_wm_region(const bContext *C)
void DEG_id_tag_update(ID *id, unsigned int flags)
void DEG_relations_tag_update(Main *bmain)
@ ID_RECALC_TRANSFORM
Definition DNA_ID.h:1054
@ ID_RECALC_GEOMETRY
Definition DNA_ID.h:1074
@ DRIVER_TYPE_PYTHON
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
Read Guarded memory(de)allocation.
#define C
Definition RandGen.cpp:29
void UI_context_update_anim_flag(const bContext *C)
@ UI_BUT_UNDO
@ UI_BUT_DRIVEN
uiBut * UI_context_active_but_prop_get(const bContext *C, PointerRNA *r_ptr, PropertyRNA **r_prop, int *r_index)
void UI_context_active_but_clear(bContext *C, wmWindow *win, ARegion *region)
bool UI_but_flag_is_set(uiBut *but, int flag)
#define NC_ANIMATION
Definition WM_types.hh:388
@ OPTYPE_INTERNAL
Definition WM_types.hh:202
@ OPTYPE_BLOCKING
Definition WM_types.hh:184
@ OPTYPE_UNDO
Definition WM_types.hh:182
#define ND_FCURVES_ORDER
Definition WM_types.hh:499
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)
Main Driver Management API calls.
Definition drivers.cc:272
const EnumPropertyItem prop_driver_create_mapping_types[]
Definition drivers.cc:810
static void driverdropper_sample(bContext *C, wmOperator *op, const wmEvent *event)
static void driverdropper_cancel(bContext *C, wmOperator *op)
static bool driverdropper_init(bContext *C, wmOperator *op)
void UI_OT_eyedropper_driver(wmOperatorType *ot)
static void driverdropper_exit(bContext *C, wmOperator *op)
static bool driverdropper_poll(bContext *C)
static wmOperatorStatus driverdropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
static wmOperatorStatus driverdropper_exec(bContext *C, wmOperator *op)
static wmOperatorStatus driverdropper_invoke(bContext *C, wmOperator *op, const wmEvent *)
uiBut * eyedropper_get_property_button_under_mouse(bContext *C, const wmEvent *event)
@ EYE_MODAL_CANCEL
@ EYE_MODAL_SAMPLE_CONFIRM
bool RNA_property_driver_editable(const PointerRNA *ptr, PropertyRNA *prop)
int RNA_enum_get(PointerRNA *ptr, const char *name)
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, const int default_value, const char *ui_name, const char *ui_description)
std::optional< std::string > RNA_path_from_ID_to_property(const PointerRNA *ptr, PropertyRNA *prop)
Definition rna_path.cc:1173
PropertyRNA * prop
ID * owner_id
Definition RNA_types.hh:51
void * data
Definition RNA_types.hh:53
PropertyRNA * rnaprop
PointerRNA rnapoin
wmEventType type
Definition WM_types.hh:757
short val
Definition WM_types.hh:759
struct ReportList * reports
struct PointerRNA * ptr
void WM_cursor_modal_set(wmWindow *win, int val)
void WM_cursor_modal_restore(wmWindow *win)
@ WM_CURSOR_EYEDROPPER
Definition wm_cursors.hh:36
wmEventHandler_Op * WM_event_add_modal_handler(bContext *C, wmOperator *op)
void WM_event_add_notifier(const bContext *C, uint type, void *reference)
@ EVT_MODAL_MAP
wmOperatorType * ot
Definition wm_files.cc:4237
uint8_t flag
Definition wm_window.cc:145