Merging r46495 through r46557 from trunk into soc-2011-tomato
[blender.git] / source / blender / editors / transform / transform_ops.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): none yet.
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/editors/transform/transform_ops.c
24  *  \ingroup edtransform
25  */
26
27
28 #include "MEM_guardedalloc.h"
29
30 #include "DNA_scene_types.h"
31
32 #include "RNA_access.h"
33 #include "RNA_define.h"
34 #include "RNA_enum_types.h"
35
36 #include "BLI_math.h"
37 #include "BLI_utildefines.h"
38
39 #include "BKE_context.h"
40 #include "BKE_global.h"
41 #include "BKE_armature.h"
42
43 #include "WM_api.h"
44 #include "WM_types.h"
45
46 #include "UI_interface.h"
47 #include "UI_resources.h"
48
49 #include "ED_screen.h"
50
51 #include "transform.h"
52
53 typedef struct TransformModeItem
54 {
55         char *idname;
56         int             mode;
57         void (*opfunc)(wmOperatorType*);
58 } TransformModeItem;
59
60 static float VecOne[3] = {1, 1, 1};
61
62 static char OP_TRANSLATION[] = "TRANSFORM_OT_translate";
63 static char OP_ROTATION[] = "TRANSFORM_OT_rotate";
64 static char OP_TOSPHERE[] = "TRANSFORM_OT_tosphere";
65 static char OP_RESIZE[] = "TRANSFORM_OT_resize";
66 static char OP_SHEAR[] = "TRANSFORM_OT_shear";
67 static char OP_WARP[] = "TRANSFORM_OT_warp";
68 static char OP_SHRINK_FATTEN[] = "TRANSFORM_OT_shrink_fatten";
69 static char OP_PUSH_PULL[] = "TRANSFORM_OT_push_pull";
70 static char OP_TILT[] = "TRANSFORM_OT_tilt";
71 static char OP_TRACKBALL[] = "TRANSFORM_OT_trackball";
72 static char OP_MIRROR[] = "TRANSFORM_OT_mirror";
73 static char OP_EDGE_SLIDE[] = "TRANSFORM_OT_edge_slide";
74 static char OP_EDGE_CREASE[] = "TRANSFORM_OT_edge_crease";
75 static char OP_SEQ_SLIDE[] = "TRANSFORM_OT_seq_slide";
76
77 void TRANSFORM_OT_translate(struct wmOperatorType *ot);
78 void TRANSFORM_OT_rotate(struct wmOperatorType *ot);
79 void TRANSFORM_OT_tosphere(struct wmOperatorType *ot);
80 void TRANSFORM_OT_resize(struct wmOperatorType *ot);
81 void TRANSFORM_OT_shear(struct wmOperatorType *ot);
82 void TRANSFORM_OT_warp(struct wmOperatorType *ot);
83 void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot);
84 void TRANSFORM_OT_push_pull(struct wmOperatorType *ot);
85 void TRANSFORM_OT_tilt(struct wmOperatorType *ot);
86 void TRANSFORM_OT_trackball(struct wmOperatorType *ot);
87 void TRANSFORM_OT_mirror(struct wmOperatorType *ot);
88 void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot);
89 void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot);
90 void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot);
91
92 static TransformModeItem transform_modes[] =
93 {
94         {OP_TRANSLATION, TFM_TRANSLATION, TRANSFORM_OT_translate},
95         {OP_ROTATION, TFM_ROTATION, TRANSFORM_OT_rotate},
96         {OP_TOSPHERE, TFM_TOSPHERE, TRANSFORM_OT_tosphere},
97         {OP_RESIZE, TFM_RESIZE, TRANSFORM_OT_resize},
98         {OP_SHEAR, TFM_SHEAR, TRANSFORM_OT_shear},
99         {OP_WARP, TFM_WARP, TRANSFORM_OT_warp},
100         {OP_SHRINK_FATTEN, TFM_SHRINKFATTEN, TRANSFORM_OT_shrink_fatten},
101         {OP_PUSH_PULL, TFM_PUSHPULL, TRANSFORM_OT_push_pull},
102         {OP_TILT, TFM_TILT, TRANSFORM_OT_tilt},
103         {OP_TRACKBALL, TFM_TRACKBALL, TRANSFORM_OT_trackball},
104         {OP_MIRROR, TFM_MIRROR, TRANSFORM_OT_mirror},
105         {OP_EDGE_SLIDE, TFM_EDGE_SLIDE, TRANSFORM_OT_edge_slide},
106         {OP_EDGE_CREASE, TFM_CREASE, TRANSFORM_OT_edge_crease},
107         {OP_SEQ_SLIDE, TFM_SEQ_SLIDE, TRANSFORM_OT_seq_slide},
108         {NULL, 0}
109 };
110
111 EnumPropertyItem transform_mode_types[] =
112 {
113         {TFM_INIT, "INIT", 0, "Init", ""},
114         {TFM_DUMMY, "DUMMY", 0, "Dummy", ""},
115         {TFM_TRANSLATION, "TRANSLATION", 0, "Translation", ""},
116         {TFM_ROTATION, "ROTATION", 0, "Rotation", ""},
117         {TFM_RESIZE, "RESIZE", 0, "Resize", ""},
118         {TFM_TOSPHERE, "TOSPHERE", 0, "Tosphere", ""},
119         {TFM_SHEAR, "SHEAR", 0, "Shear", ""},
120         {TFM_WARP, "WARP", 0, "Warp", ""},
121         {TFM_SHRINKFATTEN, "SHRINKFATTEN", 0, "Shrinkfatten", ""},
122         {TFM_TILT, "TILT", 0, "Tilt", ""},
123         {TFM_TRACKBALL, "TRACKBALL", 0, "Trackball", ""},
124         {TFM_PUSHPULL, "PUSHPULL", 0, "Pushpull", ""},
125         {TFM_CREASE, "CREASE", 0, "Crease", ""},
126         {TFM_MIRROR, "MIRROR", 0, "Mirror", ""},
127         {TFM_BONESIZE, "BONE_SIZE", 0, "Bonesize", ""},
128         {TFM_BONE_ENVELOPE, "BONE_ENVELOPE", 0, "Bone_Envelope", ""},
129         {TFM_CURVE_SHRINKFATTEN, "CURVE_SHRINKFATTEN", 0, "Curve_Shrinkfatten", ""},
130         {TFM_BONE_ROLL, "BONE_ROLL", 0, "Bone_Roll", ""},
131         {TFM_TIME_TRANSLATE, "TIME_TRANSLATE", 0, "Time_Translate", ""},
132         {TFM_TIME_SLIDE, "TIME_SLIDE", 0, "Time_Slide", ""},
133         {TFM_TIME_SCALE, "TIME_SCALE", 0, "Time_Scale", ""},
134         {TFM_TIME_EXTEND, "TIME_EXTEND", 0, "Time_Extend", ""},
135         {TFM_BAKE_TIME, "BAKE_TIME", 0, "Bake_Time", ""},
136         {TFM_BEVEL, "BEVEL", 0, "Bevel", ""},
137         {TFM_BWEIGHT, "BWEIGHT", 0, "Bweight", ""},
138         {TFM_ALIGN, "ALIGN", 0, "Align", ""},
139         {TFM_EDGE_SLIDE, "EDGESLIDE", 0, "Edge Slide", ""},
140         {TFM_SEQ_SLIDE, "SEQSLIDE", 0, "Sequence Slide", ""},
141         {0, NULL, 0, NULL, NULL}
142 };
143
144 static int snap_type_exec(bContext *C, wmOperator *op)
145 {
146         ToolSettings *ts= CTX_data_tool_settings(C);
147
148         ts->snap_mode = RNA_enum_get(op->ptr, "type");
149
150         WM_event_add_notifier(C, NC_SCENE|ND_TOOLSETTINGS, NULL); /* header redraw */
151
152         return OPERATOR_FINISHED;
153 }
154
155 static void TRANSFORM_OT_snap_type(wmOperatorType *ot)
156 {
157         /* identifiers */
158         ot->name = "Snap Type";
159         ot->description = "Set the snap element type";
160         ot->idname = "TRANSFORM_OT_snap_type";
161
162         /* api callbacks */
163         ot->invoke = WM_menu_invoke;
164         ot->exec = snap_type_exec;
165
166         ot->poll = ED_operator_areaactive;
167
168         /* flags */
169         ot->flag = OPTYPE_UNDO;
170
171         /* props */
172         ot->prop = RNA_def_enum(ot->srna, "type", snap_element_items, 0, "Type", "Set the snap element type");
173
174 }
175
176 static int select_orientation_exec(bContext *C, wmOperator *op)
177 {
178         int orientation = RNA_enum_get(op->ptr, "orientation");
179
180         BIF_selectTransformOrientationValue(C, orientation);
181         
182         WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
183
184         return OPERATOR_FINISHED;
185 }
186
187 static int select_orientation_invoke(bContext *C, wmOperator *UNUSED(op), wmEvent *UNUSED(event))
188 {
189         uiPopupMenu *pup;
190         uiLayout *layout;
191
192         pup= uiPupMenuBegin(C, "Orientation", ICON_NONE);
193         layout= uiPupMenuLayout(pup);
194         uiItemsEnumO(layout, "TRANSFORM_OT_select_orientation", "orientation");
195         uiPupMenuEnd(C, pup);
196
197         return OPERATOR_CANCELLED;
198 }
199
200 static void TRANSFORM_OT_select_orientation(struct wmOperatorType *ot)
201 {
202         PropertyRNA *prop;
203
204         /* identifiers */
205         ot->name   = "Select Orientation";
206         ot->description = "Select transformation orientation";
207         ot->idname = "TRANSFORM_OT_select_orientation";
208         ot->flag   = OPTYPE_UNDO;
209
210         /* api callbacks */
211         ot->invoke = select_orientation_invoke;
212         ot->exec   = select_orientation_exec;
213         ot->poll   = ED_operator_view3d_active;
214
215         prop= RNA_def_property(ot->srna, "orientation", PROP_ENUM, PROP_NONE);
216         RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation");
217         RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
218 }
219
220
221 static int delete_orientation_exec(bContext *C, wmOperator *UNUSED(op))
222 {
223         View3D *v3d = CTX_wm_view3d(C);
224         int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
225
226         BIF_removeTransformOrientationIndex(C, selected_index);
227         
228         WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
229         WM_event_add_notifier(C, NC_SCENE|NA_EDITED, CTX_data_scene(C));
230
231         return OPERATOR_FINISHED;
232 }
233
234 static int delete_orientation_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
235 {
236         return delete_orientation_exec(C, op);
237 }
238
239 static int delete_orientation_poll(bContext *C)
240 {
241         int selected_index = -1;
242         View3D *v3d = CTX_wm_view3d(C);
243         
244         if (ED_operator_areaactive(C) == 0)
245                 return 0;
246         
247         
248         if (v3d) {
249                 selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
250         }
251         
252         return selected_index >= 0;
253 }
254
255 static void TRANSFORM_OT_delete_orientation(struct wmOperatorType *ot)
256 {
257         /* identifiers */
258         ot->name   = "Delete Orientation";
259         ot->description = "Delete transformation orientation";
260         ot->idname = "TRANSFORM_OT_delete_orientation";
261         ot->flag   = OPTYPE_UNDO;
262
263         /* api callbacks */
264         ot->invoke = delete_orientation_invoke;
265         ot->exec   = delete_orientation_exec;
266         ot->poll   = delete_orientation_poll;
267 }
268
269 static int create_orientation_exec(bContext *C, wmOperator *op)
270 {
271         char name[MAX_NAME];
272         int use = RNA_boolean_get(op->ptr, "use");
273         int overwrite = RNA_boolean_get(op->ptr, "overwrite");
274         
275         RNA_string_get(op->ptr, "name", name);
276
277         BIF_createTransformOrientation(C, op->reports, name, use, overwrite);
278
279         WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
280         WM_event_add_notifier(C, NC_SCENE|NA_EDITED, CTX_data_scene(C));
281         
282         return OPERATOR_FINISHED;
283 }
284
285 static int create_orientation_invoke(bContext *C, wmOperator *op, wmEvent *UNUSED(event))
286 {
287         return create_orientation_exec(C, op);
288 }
289
290 static void TRANSFORM_OT_create_orientation(struct wmOperatorType *ot)
291 {
292         /* identifiers */
293         ot->name   = "Create Orientation";
294         ot->description = "Create transformation orientation from selection";
295         ot->idname = "TRANSFORM_OT_create_orientation";
296         ot->flag   = OPTYPE_REGISTER|OPTYPE_UNDO;
297
298         /* api callbacks */
299         ot->invoke = create_orientation_invoke;
300         ot->exec   = create_orientation_exec;
301         ot->poll   = ED_operator_areaactive;
302         ot->flag   = OPTYPE_REGISTER|OPTYPE_UNDO;
303
304         RNA_def_string(ot->srna, "name", "", MAX_NAME, "Name", "Text to insert at the cursor position");
305         RNA_def_boolean(ot->srna, "use", 0, "Use after creation", "Select orientation after its creation");
306         RNA_def_boolean(ot->srna, "overwrite", 0, "Overwrite previous", "Overwrite previously created orientation with same name");
307 }
308
309 static void transformops_exit(bContext *C, wmOperator *op)
310 {
311         saveTransform(C, op->customdata, op);
312         MEM_freeN(op->customdata);
313         op->customdata = NULL;
314         G.moving = 0;
315 }
316
317 static int transformops_data(bContext *C, wmOperator *op, wmEvent *event)
318 {
319         int retval = 1;
320         if (op->customdata == NULL) {
321                 TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data2");
322                 TransformModeItem *tmode;
323                 int mode = -1;
324
325                 for (tmode = transform_modes; tmode->idname; tmode++) {
326                         if (op->type->idname == tmode->idname) {
327                                 mode = tmode->mode;
328                                 break;
329                         }
330                 }
331
332                 if (mode == -1) {
333                         mode = RNA_enum_get(op->ptr, "mode");
334                 }
335
336                 retval = initTransform(C, t, op, event, mode);
337                 G.moving = 1;
338
339                 /* store data */
340                 if (retval) {
341                         op->customdata = t;
342                 }
343                 else {
344                         MEM_freeN(t);
345                 }
346         }
347
348         return retval; /* return 0 on error */
349 }
350
351 static int transform_modal(bContext *C, wmOperator *op, wmEvent *event)
352 {
353         int exit_code;
354
355         TransInfo *t = op->customdata;
356
357 #if 0
358         // stable 2D mouse coords map to different 3D coords while the 3D mouse is active
359         // in other words, 2D deltas are no longer good enough!
360         // disable until individual 'transformers' behave better
361
362         if (event->type == NDOF_MOTION)
363                 return OPERATOR_PASS_THROUGH;
364 #endif
365
366         /* XXX insert keys are called here, and require context */
367         t->context= C;
368         exit_code = transformEvent(t, event);
369         t->context= NULL;
370
371         transformApply(C, t);
372
373         exit_code |= transformEnd(C, t);
374
375         if ((exit_code & OPERATOR_RUNNING_MODAL) == 0) {
376                 transformops_exit(C, op);
377                 exit_code &= ~OPERATOR_PASS_THROUGH; /* preventively remove passthrough */
378         }
379
380         return exit_code;
381 }
382
383 static int transform_cancel(bContext *C, wmOperator *op)
384 {
385         TransInfo *t = op->customdata;
386
387         t->state = TRANS_CANCEL;
388         transformEnd(C, t);
389         transformops_exit(C, op);
390
391         return OPERATOR_CANCELLED;
392 }
393
394 static int transform_exec(bContext *C, wmOperator *op)
395 {
396         TransInfo *t;
397
398         if (!transformops_data(C, op, NULL)) {
399                 G.moving = 0;
400                 return OPERATOR_CANCELLED;
401         }
402
403         t = op->customdata;
404
405         t->options |= CTX_AUTOCONFIRM;
406
407         transformApply(C, t);
408
409         transformEnd(C, t);
410
411         transformops_exit(C, op);
412         
413         WM_event_add_notifier(C, NC_OBJECT|ND_TRANSFORM, NULL);
414
415         return OPERATOR_FINISHED;
416 }
417
418 static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
419 {
420         if (!transformops_data(C, op, event)) {
421                 G.moving = 0;
422                 return OPERATOR_CANCELLED;
423         }
424
425         if (RNA_struct_property_is_set(op->ptr, "value")) {
426                 return transform_exec(C, op);
427         }
428         else {
429                 /* add temp handler */
430                 WM_event_add_modal_handler(C, op);
431
432                 op->flag |= OP_GRAB_POINTER; // XXX maybe we want this with the manipulator only?
433                 return OPERATOR_RUNNING_MODAL;
434         }
435 }
436
437 void Transform_Properties(struct wmOperatorType *ot, int flags)
438 {
439         PropertyRNA *prop;
440
441         if (flags & P_AXIS) {
442                 prop= RNA_def_property(ot->srna, "axis", PROP_FLOAT, PROP_DIRECTION);
443                 RNA_def_property_array(prop, 3);
444                 /* Make this not hidden when there's a nice axis selection widget */
445                 RNA_def_property_flag(prop, PROP_HIDDEN);
446                 RNA_def_property_ui_text(prop, "Axis", "The axis around which the transformation occurs");
447
448         }
449
450         if (flags & P_CONSTRAINT) {
451                 RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", "");
452                 prop= RNA_def_property(ot->srna, "constraint_orientation", PROP_ENUM, PROP_NONE);
453                 RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation");
454                 RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
455
456                 
457         }
458
459         if (flags & P_MIRROR) {
460                 RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
461         }
462
463
464         if (flags & P_PROPORTIONAL) {
465                 RNA_def_enum(ot->srna, "proportional", proportional_editing_items, 0, "Proportional Editing", "");
466                 RNA_def_enum(ot->srna, "proportional_edit_falloff", proportional_falloff_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode");
467                 RNA_def_float(ot->srna, "proportional_size", 1, 0.00001f, FLT_MAX, "Proportional Size", "", 0.001, 100);
468         }
469
470         if (flags & P_SNAP) {
471                 prop= RNA_def_boolean(ot->srna, "snap", 0, "Use Snapping Options", "");
472                 RNA_def_property_flag(prop, PROP_HIDDEN);
473
474                 if (flags & P_GEO_SNAP) {
475                         prop= RNA_def_enum(ot->srna, "snap_target", snap_target_items, 0, "Target", "");
476                         RNA_def_property_flag(prop, PROP_HIDDEN);
477                         prop= RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX);
478                         RNA_def_property_flag(prop, PROP_HIDDEN);
479                         
480                         if (flags & P_ALIGN_SNAP) {
481                                 prop= RNA_def_boolean(ot->srna, "snap_align", 0, "Align with Point Normal", "");
482                                 RNA_def_property_flag(prop, PROP_HIDDEN);
483                                 prop= RNA_def_float_vector(ot->srna, "snap_normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal", "", -FLT_MAX, FLT_MAX);
484                                 RNA_def_property_flag(prop, PROP_HIDDEN);
485                         }
486                 }
487         }
488
489         if (flags & P_OPTIONS) {
490                 RNA_def_boolean(ot->srna, "texture_space", 0, "Edit Texture Space", "Edit Object data texture space");
491         }
492
493         if (flags & P_CORRECT_UV) {
494                 RNA_def_boolean(ot->srna, "correct_uv", 0, "Correct UVs", "Correct UV coordinates when transforming");
495         }
496
497         // Add confirm method all the time. At the end because it's not really that important and should be hidden only in log, not in keymap edit
498         /*prop =*/ RNA_def_boolean(ot->srna, "release_confirm", 0, "Confirm on Release", "Always confirm operation when releasing button");
499         //RNA_def_property_flag(prop, PROP_HIDDEN);
500 }
501
502 void TRANSFORM_OT_translate(struct wmOperatorType *ot)
503 {
504         /* identifiers */
505         ot->name   = "Translate";
506         ot->description = "Translate (move) selected items";
507         ot->idname = OP_TRANSLATION;
508         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
509
510         /* api callbacks */
511         ot->invoke = transform_invoke;
512         ot->exec   = transform_exec;
513         ot->modal  = transform_modal;
514         ot->cancel = transform_cancel;
515         ot->poll   = ED_operator_screenactive;
516
517         RNA_def_float_vector_xyz(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
518
519         Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_ALIGN_SNAP|P_OPTIONS);
520 }
521
522 void TRANSFORM_OT_resize(struct wmOperatorType *ot)
523 {
524         /* identifiers */
525         ot->name   = "Resize";
526         ot->description = "Scale (resize) selected items"; 
527         ot->idname = OP_RESIZE;
528         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
529
530         /* api callbacks */
531         ot->invoke = transform_invoke;
532         ot->exec   = transform_exec;
533         ot->modal  = transform_modal;
534         ot->cancel = transform_cancel;
535         ot->poll   = ED_operator_screenactive;
536
537         RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
538
539         Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_GEO_SNAP|P_OPTIONS);
540 }
541
542
543 void TRANSFORM_OT_trackball(struct wmOperatorType *ot)
544 {
545         /* identifiers */
546         ot->name   = "Trackball";
547         ot->description = "Trackball style rotation of selected items";
548         ot->idname = OP_TRACKBALL;
549         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
550
551         /* api callbacks */
552         ot->invoke = transform_invoke;
553         ot->exec   = transform_exec;
554         ot->modal  = transform_modal;
555         ot->cancel = transform_cancel;
556         ot->poll   = ED_operator_screenactive;
557
558         RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
559
560         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
561 }
562
563 void TRANSFORM_OT_rotate(struct wmOperatorType *ot)
564 {
565         /* identifiers */
566         ot->name   = "Rotate";
567         ot->description = "Rotate selected items";
568         ot->idname = OP_ROTATION;
569         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
570
571         /* api callbacks */
572         ot->invoke = transform_invoke;
573         ot->exec   = transform_exec;
574         ot->modal  = transform_modal;
575         ot->cancel = transform_cancel;
576         ot->poll   = ED_operator_screenactive;
577
578         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
579
580         Transform_Properties(ot, P_AXIS|P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_GEO_SNAP);
581 }
582
583 void TRANSFORM_OT_tilt(struct wmOperatorType *ot)
584 {
585         /* identifiers */
586         ot->name   = "Tilt";
587         /* optionals - 
588          * "Tilt selected vertices"
589          * "Specify an extra axis rotation for selected vertices of 3d curve" */
590         ot->description = "Tilt selected control vertices of 3d curve"; 
591         ot->idname = OP_TILT;
592         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
593
594         /* api callbacks */
595         ot->invoke = transform_invoke;
596         ot->exec   = transform_exec;
597         ot->modal  = transform_modal;
598         ot->cancel = transform_cancel;
599         ot->poll   = ED_operator_editcurve_3d;
600
601         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
602
603         Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_SNAP);
604 }
605
606 void TRANSFORM_OT_warp(struct wmOperatorType *ot)
607 {
608         /* identifiers */
609         ot->name   = "Warp";
610         ot->description = "Warp selected items around the cursor";
611         ot->idname = OP_WARP;
612         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
613
614         /* api callbacks */
615         ot->invoke = transform_invoke;
616         ot->exec   = transform_exec;
617         ot->modal  = transform_modal;
618         ot->cancel = transform_cancel;
619         ot->poll   = ED_operator_screenactive;
620
621         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
622
623         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
624         // XXX Warp axis?
625 }
626
627 void TRANSFORM_OT_shear(struct wmOperatorType *ot)
628 {
629         /* identifiers */
630         ot->name   = "Shear";
631         ot->description = "Shear selected items along the horizontal screen axis";
632         ot->idname = OP_SHEAR;
633         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
634
635         /* api callbacks */
636         ot->invoke = transform_invoke;
637         ot->exec   = transform_exec;
638         ot->modal  = transform_modal;
639         ot->cancel = transform_cancel;
640         ot->poll   = ED_operator_screenactive;
641
642         RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
643
644         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
645         // XXX Shear axis?
646 }
647
648 void TRANSFORM_OT_push_pull(struct wmOperatorType *ot)
649 {
650         /* identifiers */
651         ot->name   = "Push/Pull";
652         ot->description = "Push/Pull selected items";
653         ot->idname = OP_PUSH_PULL;
654         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
655
656         /* api callbacks */
657         ot->invoke = transform_invoke;
658         ot->exec   = transform_exec;
659         ot->modal  = transform_modal;
660         ot->cancel = transform_cancel;
661         ot->poll   = ED_operator_screenactive;
662
663         RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Distance", "", -FLT_MAX, FLT_MAX);
664
665         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
666 }
667
668 void TRANSFORM_OT_shrink_fatten(struct wmOperatorType *ot)
669 {
670         /* identifiers */
671         ot->name   = "Shrink/Fatten";
672         ot->description = "Shrink/fatten selected vertices along normals";
673         ot->idname = OP_SHRINK_FATTEN;
674         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
675
676         /* api callbacks */
677         ot->invoke = transform_invoke;
678         ot->exec   = transform_exec;
679         ot->modal  = transform_modal;
680         ot->cancel = transform_cancel;
681         ot->poll   = ED_operator_editmesh;
682
683         RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
684
685         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
686 }
687
688 void TRANSFORM_OT_tosphere(struct wmOperatorType *ot)
689 {
690         /* identifiers */
691         ot->name   = "To Sphere";
692         //added "around mesh center" to differentiate between "MESH_OT_vertices_to_sphere()" 
693         ot->description = "Move selected vertices outward in a spherical shape around mesh center";
694         ot->idname = OP_TOSPHERE;
695         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
696
697         /* api callbacks */
698         ot->invoke = transform_invoke;
699         ot->exec   = transform_exec;
700         ot->modal  = transform_modal;
701         ot->cancel = transform_cancel;
702         ot->poll   = ED_operator_screenactive;
703
704         RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1);
705
706         Transform_Properties(ot, P_PROPORTIONAL|P_MIRROR|P_SNAP);
707 }
708
709 void TRANSFORM_OT_mirror(struct wmOperatorType *ot)
710 {
711         /* identifiers */
712         ot->name   = "Mirror";
713         ot->description = "Mirror selected vertices around one or more axes";
714         ot->idname = OP_MIRROR;
715         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
716
717         /* api callbacks */
718         ot->invoke = transform_invoke;
719         ot->exec   = transform_exec;
720         ot->modal  = transform_modal;
721         ot->cancel = transform_cancel;
722         ot->poll   = ED_operator_screenactive;
723
724         Transform_Properties(ot, P_CONSTRAINT|P_PROPORTIONAL);
725 }
726
727 void TRANSFORM_OT_edge_slide(struct wmOperatorType *ot)
728 {
729         /* identifiers */
730         ot->name   = "Edge Slide";
731         ot->description = "Slide an edge loop along a mesh"; 
732         ot->idname = OP_EDGE_SLIDE;
733         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
734
735         /* api callbacks */
736         ot->invoke = transform_invoke;
737         ot->exec   = transform_exec;
738         ot->modal  = transform_modal;
739         ot->cancel = transform_cancel;
740         ot->poll   = ED_operator_editmesh;
741
742         RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
743
744         Transform_Properties(ot, P_MIRROR|P_SNAP|P_CORRECT_UV);
745 }
746
747 void TRANSFORM_OT_edge_crease(struct wmOperatorType *ot)
748 {
749         /* identifiers */
750         ot->name   = "Edge Crease";
751         ot->description = "Change the crease of edges";
752         ot->idname = OP_EDGE_CREASE;
753         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
754
755         /* api callbacks */
756         ot->invoke = transform_invoke;
757         ot->exec   = transform_exec;
758         ot->modal  = transform_modal;
759         ot->cancel = transform_cancel;
760         ot->poll   = ED_operator_editmesh;
761
762         RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
763
764         Transform_Properties(ot, P_SNAP);
765 }
766
767 void TRANSFORM_OT_seq_slide(struct wmOperatorType *ot)
768 {
769         /* identifiers */
770         ot->name   = "Sequence Slide";
771         ot->description = "Slide a sequence strip in time";
772         ot->idname = OP_SEQ_SLIDE;
773         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
774
775         /* api callbacks */
776         ot->invoke = transform_invoke;
777         ot->exec   = transform_exec;
778         ot->modal  = transform_modal;
779         ot->cancel = transform_cancel;
780         ot->poll   = ED_operator_sequencer_active;
781
782         RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "Angle", "", -FLT_MAX, FLT_MAX);
783
784         Transform_Properties(ot, P_SNAP);
785 }
786
787 void TRANSFORM_OT_transform(struct wmOperatorType *ot)
788 {
789         PropertyRNA *prop;
790
791         /* identifiers */
792         ot->name   = "Transform";
793         ot->description = "Transform selected items by mode type";
794         ot->idname = "TRANSFORM_OT_transform";
795         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
796
797         /* api callbacks */
798         ot->invoke = transform_invoke;
799         ot->exec   = transform_exec;
800         ot->modal  = transform_modal;
801         ot->cancel = transform_cancel;
802         ot->poll   = ED_operator_screenactive;
803
804         prop= RNA_def_enum(ot->srna, "mode", transform_mode_types, TFM_TRANSLATION, "Mode", "");
805         RNA_def_property_flag(prop, PROP_HIDDEN);
806
807         RNA_def_float_vector(ot->srna, "value", 4, NULL, -FLT_MAX, FLT_MAX, "Values", "", -FLT_MAX, FLT_MAX);
808
809         Transform_Properties(ot, P_AXIS|P_CONSTRAINT|P_PROPORTIONAL|P_MIRROR|P_ALIGN_SNAP);
810 }
811
812 void transform_operatortypes(void)
813 {
814         TransformModeItem *tmode;
815
816         for (tmode = transform_modes; tmode->idname; tmode++) {
817                 WM_operatortype_append(tmode->opfunc);
818         }
819
820         WM_operatortype_append(TRANSFORM_OT_transform);
821
822         WM_operatortype_append(TRANSFORM_OT_select_orientation);
823         WM_operatortype_append(TRANSFORM_OT_create_orientation);
824         WM_operatortype_append(TRANSFORM_OT_delete_orientation);
825
826         WM_operatortype_append(TRANSFORM_OT_snap_type);
827 }
828
829 void transform_keymap_for_space(wmKeyConfig *keyconf, wmKeyMap *keymap, int spaceid)
830 {
831         wmKeyMapItem *kmi;
832         wmKeyMap *modalmap;
833         
834         /* transform.c, only adds modal map once, checks if it's there */
835         modalmap = transform_modal_keymap(keyconf);
836
837         /* assign map to operators only the first time */
838         if (modalmap) {
839                 TransformModeItem *tmode;
840
841                 for (tmode = transform_modes; tmode->idname; tmode++) {
842                         WM_modalkeymap_assign(modalmap, tmode->idname);
843                 }
844                 WM_modalkeymap_assign(modalmap, "TRANSFORM_OT_transform");
845         }
846         
847         switch (spaceid) {
848                 case SPACE_VIEW3D:
849                         WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
850
851                         WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
852
853                         WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
854
855                         WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
856
857                         WM_keymap_add_item(keymap, OP_WARP, WKEY, KM_PRESS, KM_SHIFT, 0);
858
859                         WM_keymap_add_item(keymap, OP_TOSPHERE, SKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
860
861                         WM_keymap_add_item(keymap, OP_SHEAR, SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
862
863                         WM_keymap_add_item(keymap, "TRANSFORM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0);
864
865                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
866                         RNA_boolean_set(kmi->ptr, "use", TRUE);
867
868                         WM_keymap_add_item(keymap, OP_MIRROR, MKEY, KM_PRESS, KM_CTRL, 0);
869
870                         kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0);
871                         RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_snap");
872
873                         WM_keymap_add_item(keymap, "TRANSFORM_OT_snap_type", TABKEY, KM_PRESS, KM_SHIFT|KM_CTRL, 0);
874
875                         kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, TKEY, KM_PRESS, KM_SHIFT, 0);
876                         RNA_boolean_set(kmi->ptr, "texture_space", TRUE);
877
878                         kmi = WM_keymap_add_item(keymap, OP_RESIZE, TKEY, KM_PRESS, KM_SHIFT|KM_ALT, 0);
879                         RNA_boolean_set(kmi->ptr, "texture_space", TRUE);
880
881                         break;
882                 case SPACE_ACTION:
883                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", GKEY, KM_PRESS, 0, 0);
884                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_TRANSLATE);
885                         
886                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
887                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_TRANSLATE);
888                         
889                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
890                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND);
891                         
892                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, 0, 0);
893                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_SCALE);
894                         
895                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", TKEY, KM_PRESS, KM_SHIFT, 0);
896                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_SLIDE);
897                         break;
898                 case SPACE_IPO:
899                         WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
900                         
901                         WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
902                         
903                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
904                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND);
905                         
906                         WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
907                         
908                         WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
909                         break;
910                 case SPACE_NLA:
911                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", GKEY, KM_PRESS, 0, 0);
912                         RNA_enum_set(kmi->ptr, "mode", TFM_TRANSLATION);
913                         
914                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
915                         RNA_enum_set(kmi->ptr, "mode", TFM_TRANSLATION);
916                         
917                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
918                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND);
919                         
920                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, 0, 0);
921                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_SCALE);
922                         break;
923                 case SPACE_NODE:
924                         WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
925
926                         kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_A, KM_ANY, 0, 0);
927                         RNA_boolean_set(kmi->ptr, "release_confirm", TRUE);
928                         kmi = WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
929
930                         WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
931
932                         WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
933
934                         /* detach and translate */
935                         WM_keymap_add_item(keymap, "NODE_OT_move_detach_links", DKEY, KM_PRESS, KM_ALT, 0);
936
937                         /* XXX release_confirm is set in the macro operator definition */
938                         WM_keymap_add_item(keymap, "NODE_OT_move_detach_links_release", EVT_TWEAK_A, KM_ANY, KM_ALT, 0);
939                         WM_keymap_add_item(keymap, "NODE_OT_move_detach_links", EVT_TWEAK_S, KM_ANY, KM_ALT, 0);
940                         break;
941                 case SPACE_SEQ:
942                         WM_keymap_add_item(keymap, OP_SEQ_SLIDE, GKEY, KM_PRESS, 0, 0);
943
944                         WM_keymap_add_item(keymap, OP_SEQ_SLIDE, EVT_TWEAK_S, KM_ANY, 0, 0);
945
946                         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", EKEY, KM_PRESS, 0, 0);
947                         RNA_enum_set(kmi->ptr, "mode", TFM_TIME_EXTEND);
948                         break;
949                 case SPACE_IMAGE:
950                         WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
951
952                         WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
953
954                         WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
955
956                         WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
957
958                         WM_keymap_add_item(keymap, OP_SHEAR, SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
959
960                         WM_keymap_add_item(keymap, "TRANSFORM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0);
961
962                         kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", TABKEY, KM_PRESS, KM_SHIFT, 0);
963                         RNA_string_set(kmi->ptr, "data_path", "tool_settings.use_snap");
964                         break;
965                 case SPACE_CLIP:
966                         WM_keymap_add_item(keymap, OP_TRANSLATION, GKEY, KM_PRESS, 0, 0);
967                         WM_keymap_add_item(keymap, OP_TRANSLATION, EVT_TWEAK_S, KM_ANY, 0, 0);
968                         WM_keymap_add_item(keymap, OP_RESIZE, SKEY, KM_PRESS, 0, 0);
969                         WM_keymap_add_item(keymap, OP_ROTATION, RKEY, KM_PRESS, 0, 0);
970                         break;
971                 default:
972                         break;
973         }
974 }
975