Blender  V2.93
interface_eyedropper_driver.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2009 Blender Foundation.
17  * All rights reserved.
18  */
19 
29 #include "MEM_guardedalloc.h"
30 
31 #include "DNA_anim_types.h"
32 #include "DNA_object_types.h"
33 #include "DNA_screen_types.h"
34 
35 #include "BKE_animsys.h"
36 #include "BKE_context.h"
37 
38 #include "DEG_depsgraph.h"
39 #include "DEG_depsgraph_build.h"
40 
41 #include "RNA_access.h"
42 #include "RNA_define.h"
43 
44 #include "UI_interface.h"
45 
46 #include "WM_api.h"
47 #include "WM_types.h"
48 
49 #include "ED_keyframing.h"
50 
52 #include "interface_intern.h"
53 
54 typedef struct DriverDropper {
55  /* Destination property (i.e. where we'll add a driver) */
58  int index;
59  bool is_undo;
60 
61  /* TODO: new target? */
63 
65 {
66  DriverDropper *ddr = MEM_callocN(sizeof(DriverDropper), __func__);
67 
68  uiBut *but = UI_context_active_but_prop_get(C, &ddr->ptr, &ddr->prop, &ddr->index);
69 
70  if ((ddr->ptr.data == NULL) || (ddr->prop == NULL) ||
71  (RNA_property_editable(&ddr->ptr, ddr->prop) == false) ||
72  (RNA_property_animateable(&ddr->ptr, ddr->prop) == false) || (but->flag & UI_BUT_DRIVEN)) {
73  MEM_freeN(ddr);
74  return false;
75  }
76  op->customdata = ddr;
77 
79 
80  return true;
81 }
82 
84 {
86 
87  if (op->customdata) {
88  MEM_freeN(op->customdata);
89  op->customdata = NULL;
90  }
91 }
92 
93 static void driverdropper_sample(bContext *C, wmOperator *op, const wmEvent *event)
94 {
97 
98  const short mapping_type = RNA_enum_get(op->ptr, "mapping_type");
99  const short flag = 0;
100 
101  /* we can only add a driver if we know what RNA property it corresponds to */
102  if (but == NULL) {
103  return;
104  }
105  /* Get paths for src... */
106  PointerRNA *target_ptr = &but->rnapoin;
107  PropertyRNA *target_prop = but->rnaprop;
108  const int target_index = but->rnaindex;
109 
110  char *target_path = RNA_path_from_ID_to_property(target_ptr, target_prop);
111 
112  /* ... and destination */
113  char *dst_path = BKE_animdata_driver_path_hack(C, &ddr->ptr, ddr->prop, NULL);
114 
115  /* Now create driver(s) */
116  if (target_path && dst_path) {
117  int success = ANIM_add_driver_with_target(op->reports,
118  ddr->ptr.owner_id,
119  dst_path,
120  ddr->index,
121  target_ptr->owner_id,
122  target_path,
123  target_index,
124  flag,
126  mapping_type);
127 
128  if (success) {
129  /* send updates */
134  }
135  }
136 
137  /* cleanup */
138  if (target_path) {
139  MEM_freeN(target_path);
140  }
141  if (dst_path) {
142  MEM_freeN(dst_path);
143  }
144 }
145 
147 {
148  driverdropper_exit(C, op);
149 }
150 
151 /* main modal status check */
152 static int driverdropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
153 {
154  DriverDropper *ddr = op->customdata;
155 
156  /* handle modal keymap */
157  if (event->type == EVT_MODAL_MAP) {
158  switch (event->val) {
159  case EYE_MODAL_CANCEL: {
160  driverdropper_cancel(C, op);
161  return OPERATOR_CANCELLED;
162  }
164  const bool is_undo = ddr->is_undo;
165  driverdropper_sample(C, op, event);
166  driverdropper_exit(C, op);
167  /* Could support finished & undo-skip. */
168  return is_undo ? OPERATOR_FINISHED : OPERATOR_CANCELLED;
169  }
170  }
171  }
172 
173  return OPERATOR_RUNNING_MODAL;
174 }
175 
176 /* Modal Operator init */
177 static int driverdropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
178 {
179  /* init */
180  if (driverdropper_init(C, op)) {
181  wmWindow *win = CTX_wm_window(C);
182  /* Workaround for de-activating the button clearing the cursor, see T76794 */
185 
186  /* add temp handler */
188 
189  return OPERATOR_RUNNING_MODAL;
190  }
191  return OPERATOR_CANCELLED;
192 }
193 
194 /* Repeat operator */
196 {
197  /* init */
198  if (driverdropper_init(C, op)) {
199  /* cleanup */
200  driverdropper_exit(C, op);
201 
202  return OPERATOR_FINISHED;
203  }
204  return OPERATOR_CANCELLED;
205 }
206 
208 {
209  if (!CTX_wm_window(C)) {
210  return false;
211  }
212  return true;
213 }
214 
216 {
217  /* identifiers */
218  ot->name = "Eyedropper Driver";
219  ot->idname = "UI_OT_eyedropper_driver";
220  ot->description = "Pick a property to use as a driver target";
221 
222  /* api callbacks */
228 
229  /* flags */
231 
232  /* properties */
234  "mapping_type",
236  0,
237  "Mapping Type",
238  "Method used to match target and driven properties");
239 }
char * BKE_animdata_driver_path_hack(struct bContext *C, struct PointerRNA *ptr, struct PropertyRNA *prop, char *base_path)
Definition: anim_data.c:732
struct ARegion * CTX_wm_region(const bContext *C)
Definition: context.c:725
struct Main * CTX_data_main(const bContext *C)
Definition: context.c:1018
struct wmWindow * CTX_wm_window(const bContext *C)
Definition: context.c:699
#define UNUSED(x)
void DEG_id_tag_update(struct ID *id, int flag)
void DEG_relations_tag_update(struct Main *bmain)
@ ID_RECALC_TRANSFORM
Definition: DNA_ID.h:599
@ ID_RECALC_GEOMETRY
Definition: DNA_ID.h:611
@ DRIVER_TYPE_PYTHON
Object is a sort of wrapper for general info.
@ OPERATOR_CANCELLED
@ OPERATOR_FINISHED
@ OPERATOR_RUNNING_MODAL
Read Guarded memory(de)allocation.
#define C
Definition: RandGen.cpp:39
@ UI_BUT_UNDO
Definition: UI_interface.h:208
@ UI_BUT_DRIVEN
Definition: UI_interface.h:203
void UI_context_active_but_clear(struct bContext *C, struct wmWindow *win, struct ARegion *region)
uiBut * UI_context_active_but_prop_get(const struct bContext *C, struct PointerRNA *r_ptr, struct PropertyRNA **r_prop, int *r_index)
void UI_context_update_anim_flag(const struct bContext *C)
bool UI_but_flag_is_set(uiBut *but, int flag)
Definition: interface.c:6087
@ OPTYPE_INTERNAL
Definition: WM_types.h:175
@ OPTYPE_BLOCKING
Definition: WM_types.h:157
@ OPTYPE_UNDO
Definition: WM_types.h:155
#define NC_ANIMATION
Definition: WM_types.h:289
#define ND_FCURVES_ORDER
Definition: WM_types.h:399
EnumPropertyItem prop_driver_create_mapping_types[]
Definition: drivers.c:891
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)
Definition: drivers.c:309
uiBut * eyedropper_get_property_button_under_mouse(bContext *C, const wmEvent *event)
static int driverdropper_exec(bContext *C, wmOperator *op)
struct DriverDropper DriverDropper
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 int driverdropper_modal(bContext *C, wmOperator *op, const wmEvent *event)
static int driverdropper_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event))
@ EYE_MODAL_SAMPLE_CONFIRM
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:45
bool RNA_property_animateable(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:2168
char * RNA_path_from_ID_to_property(PointerRNA *ptr, PropertyRNA *prop)
Definition: rna_access.c:6027
bool RNA_property_editable(PointerRNA *ptr, PropertyRNA *prop_orig)
Definition: rna_access.c:2073
int RNA_enum_get(PointerRNA *ptr, const char *name)
Definition: rna_access.c:6402
PropertyRNA * RNA_def_enum(StructOrFunctionRNA *cont_, const char *identifier, const EnumPropertyItem *items, int default_value, const char *ui_name, const char *ui_description)
Definition: rna_define.c:3771
void * data
Definition: RNA_types.h:52
struct ID * owner_id
Definition: RNA_types.h:50
short val
Definition: WM_types.h:579
short type
Definition: WM_types.h:577
int(* invoke)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:752
const char * name
Definition: WM_types.h:721
int(* modal)(struct bContext *, struct wmOperator *, const struct wmEvent *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:768
const char * idname
Definition: WM_types.h:723
bool(* poll)(struct bContext *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:776
void(* cancel)(struct bContext *, struct wmOperator *)
Definition: WM_types.h:760
struct StructRNA * srna
Definition: WM_types.h:802
const char * description
Definition: WM_types.h:726
int(* exec)(struct bContext *, struct wmOperator *) ATTR_WARN_UNUSED_RESULT
Definition: WM_types.h:736
struct ReportList * reports
struct PointerRNA * ptr
void WM_cursor_modal_set(wmWindow *win, int val)
Definition: wm_cursors.c:207
void WM_cursor_modal_restore(wmWindow *win)
Definition: wm_cursors.c:216
@ WM_CURSOR_EYEDROPPER
Definition: wm_cursors.h:51
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.c:3156