69819da8cc2c569dd0b8ec9bc7a35b9ff24a2e7b
[blender.git] / source / blender / editors / transform / transform_ops.c
1 /**
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version.
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
19  *
20  * Contributor(s): none yet.
21  *
22  * ***** END GPL LICENSE BLOCK *****
23  */
24
25 #include "MEM_guardedalloc.h"
26
27 #include "DNA_scene_types.h"
28 #include "DNA_space_types.h"
29 #include "DNA_windowmanager_types.h"
30
31 #include "RNA_access.h"
32 #include "RNA_define.h"
33 #include "RNA_enum_types.h"
34
35 #include "BLI_arithb.h"
36
37 #include "BKE_utildefines.h"
38 #include "BKE_context.h"
39 #include "BKE_global.h"
40
41 #include "WM_api.h"
42 #include "WM_types.h"
43
44 #include "UI_interface.h"
45
46 #include "ED_screen.h"
47
48 #include "transform.h"
49
50 typedef struct TransformModeItem
51 {
52         char *idname;
53         int             mode;
54 } TransformModeItem;
55
56 static float VecOne[3] = {1, 1, 1};
57
58 /* need constants for this */
59 EnumPropertyItem proportional_mode_types[] = {
60                 {0, "OFF", 0, "Off", ""},
61                 {1, "ON", 0, "On", ""},
62                 {2, "CONNECTED", 0, "Connected", ""},
63                 {0, NULL, 0, NULL, NULL}
64 };
65
66 EnumPropertyItem snap_mode_types[] = {
67                 {SCE_SNAP_TARGET_CLOSEST, "CLOSEST", 0, "Closest", ""},
68                 {SCE_SNAP_TARGET_CENTER,  "CENTER", 0, "Center", ""},
69                 {SCE_SNAP_TARGET_MEDIAN,  "MEDIAN", 0, "Median", ""},
70                 {SCE_SNAP_TARGET_ACTIVE,  "ACTIVE", 0, "Active", ""},
71                 {0, NULL, 0, NULL, NULL}
72 };
73
74 EnumPropertyItem proportional_falloff_types[] = {
75                 {PROP_SMOOTH, "SMOOTH", 0, "Smooth", ""},
76                 {PROP_SPHERE, "SPHERE", 0, "Sphere", ""},
77                 {PROP_ROOT, "ROOT", 0, "Root", ""},
78                 {PROP_SHARP, "SHARP", 0, "Sharp", ""},
79                 {PROP_LIN, "LINEAR", 0, "Linear", ""},
80                 {PROP_CONST, "CONSTANT", 0, "Constant", ""},
81                 {PROP_RANDOM, "RANDOM", 0, "Random", ""},
82                 {0, NULL, 0, NULL, NULL}
83 };
84
85 EnumPropertyItem orientation_items[]= {
86         {V3D_MANIP_GLOBAL, "GLOBAL", 0, "Global", ""},
87         {V3D_MANIP_NORMAL, "NORMAL", 0, "Normal", ""},
88         {V3D_MANIP_LOCAL, "LOCAL", 0, "Local", ""},
89         {V3D_MANIP_VIEW, "VIEW", 0, "View", ""},
90         {0, NULL, 0, NULL, NULL}};
91
92 char OP_TRANSLATION[] = "TFM_OT_translate";
93 char OP_ROTATION[] = "TFM_OT_rotate";
94 char OP_TOSPHERE[] = "TFM_OT_tosphere";
95 char OP_RESIZE[] = "TFM_OT_resize";
96 char OP_SHEAR[] = "TFM_OT_shear";
97 char OP_WARP[] = "TFM_OT_warp";
98 char OP_SHRINK_FATTEN[] = "TFM_OT_shrink_fatten";
99 char OP_TILT[] = "TFM_OT_tilt";
100 char OP_TRACKBALL[] = "TFM_OT_trackball";
101 char OP_MIRROR[] = "TFM_OT_mirror";
102
103
104 TransformModeItem transform_modes[] =
105 {
106         {OP_TRANSLATION, TFM_TRANSLATION},
107         {OP_ROTATION, TFM_ROTATION},
108         {OP_TOSPHERE, TFM_TOSPHERE},
109         {OP_RESIZE, TFM_RESIZE},
110         {OP_SHEAR, TFM_SHEAR},
111         {OP_WARP, TFM_WARP},
112         {OP_SHRINK_FATTEN, TFM_SHRINKFATTEN},
113         {OP_TILT, TFM_TILT},
114         {OP_TRACKBALL, TFM_TRACKBALL},
115         {OP_MIRROR, TFM_MIRROR},
116         {NULL, 0}
117 };
118
119 static int select_orientation_exec(bContext *C, wmOperator *op)
120 {
121         int orientation = RNA_enum_get(op->ptr, "orientation");
122
123         BIF_selectTransformOrientationValue(C, orientation);
124
125         return OPERATOR_FINISHED;
126 }
127
128 static int select_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event)
129 {
130         uiPopupMenu *pup;
131         uiLayout *layout;
132
133         pup= uiPupMenuBegin(C, "Orientation", 0);
134         layout= uiPupMenuLayout(pup);
135         uiItemsEnumO(layout, "TFM_OT_select_orientation", "orientation");
136         uiPupMenuEnd(C, pup);
137
138         return OPERATOR_CANCELLED;
139 }
140
141 static EnumPropertyItem *select_orientation_itemf(bContext *C, PointerRNA *ptr, int *free)
142 {
143         *free= 1;
144         return BIF_enumTransformOrientation(C);
145 }
146
147 void TFM_OT_select_orientation(struct wmOperatorType *ot)
148 {
149         PropertyRNA *prop;
150
151         /* identifiers */
152         ot->name   = "Select Orientation";
153         ot->description= "Select orientation type.";
154         ot->idname = "TFM_OT_select_orientation";
155
156         /* api callbacks */
157         ot->invoke = select_orientation_invoke;
158         ot->exec   = select_orientation_exec;
159         ot->poll   = ED_operator_areaactive;
160
161         prop= RNA_def_enum(ot->srna, "orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN");
162         RNA_def_enum_funcs(prop, select_orientation_itemf);
163 }
164
165 static void transformops_exit(bContext *C, wmOperator *op)
166 {
167         saveTransform(C, op->customdata, op);
168         MEM_freeN(op->customdata);
169         op->customdata = NULL;
170         G.moving = 0;
171 }
172
173 static int transformops_data(bContext *C, wmOperator *op, wmEvent *event)
174 {
175         int retval = 1;
176         if (op->customdata == NULL)
177         {
178                 TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data");
179                 TransformModeItem *tmode;
180                 int mode = -1;
181
182                 for (tmode = transform_modes; tmode->idname; tmode++)
183                 {
184                         if (op->type->idname == tmode->idname)
185                         {
186                                 mode = tmode->mode;
187                         }
188                 }
189
190                 if (mode == -1)
191                 {
192                         mode = RNA_int_get(op->ptr, "mode");
193                 }
194
195                 retval = initTransform(C, t, op, event, mode);
196                 G.moving = 1;
197
198                 /* store data */
199                 op->customdata = t;
200         }
201
202         return retval; /* return 0 on error */
203 }
204
205 static int transform_modal(bContext *C, wmOperator *op, wmEvent *event)
206 {
207         int exit_code;
208
209         TransInfo *t = op->customdata;
210
211         transformEvent(t, event);
212
213         transformApply(C, t);
214
215
216         exit_code = transformEnd(C, t);
217
218         if (exit_code != OPERATOR_RUNNING_MODAL)
219         {
220                 transformops_exit(C, op);
221         }
222
223         return exit_code;
224 }
225
226 static int transform_cancel(bContext *C, wmOperator *op)
227 {
228         TransInfo *t = op->customdata;
229
230         t->state = TRANS_CANCEL;
231         transformEnd(C, t);
232         transformops_exit(C, op);
233
234         return OPERATOR_CANCELLED;
235 }
236
237 static int transform_exec(bContext *C, wmOperator *op)
238 {
239         TransInfo *t;
240
241         if (!transformops_data(C, op, NULL))
242         {
243                 return OPERATOR_CANCELLED;
244         }
245
246         t = op->customdata;
247
248         t->options |= CTX_AUTOCONFIRM;
249
250         transformApply(C, t);
251
252         transformEnd(C, t);
253
254         transformops_exit(C, op);
255
256         return OPERATOR_FINISHED;
257 }
258
259 static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
260 {
261         if (!transformops_data(C, op, event))
262         {
263                 return OPERATOR_CANCELLED;
264         }
265
266         if(RNA_property_is_set(op->ptr, "value")) {
267                 return transform_exec(C, op);
268         }
269         else {
270                 TransInfo *t = op->customdata;
271
272                 /* add temp handler */
273                 WM_event_add_modal_handler(C, op);
274
275                 t->flag |= T_MODAL; // XXX meh maybe somewhere else
276
277                 return OPERATOR_RUNNING_MODAL;
278         }
279 }
280
281 void Properties_Proportional(struct wmOperatorType *ot)
282 {
283         RNA_def_enum(ot->srna, "proportional", proportional_mode_types, 0, "Proportional Editing", "");
284         RNA_def_enum(ot->srna, "proportional_editing_falloff", prop_mode_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode.");
285         RNA_def_float(ot->srna, "proportional_size", 1, 0, FLT_MAX, "Proportional Size", "", 0, 100);
286 }
287
288 void Properties_Snapping(struct wmOperatorType *ot, short align)
289 {
290         RNA_def_boolean(ot->srna, "snap", 0, "Snap to Point", "");
291         RNA_def_enum(ot->srna, "snap_mode", snap_mode_types, 0, "Mode", "");
292         RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX);
293
294         if (align)
295         {
296                 RNA_def_boolean(ot->srna, "snap_align", 0, "Align with Point Normal", "");
297                 RNA_def_float_vector(ot->srna, "snap_normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal", "", -FLT_MAX, FLT_MAX);
298         }
299 }
300
301 void Properties_Constraints(struct wmOperatorType *ot)
302 {
303         PropertyRNA *prop;
304
305         RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", "");
306         prop= RNA_def_enum(ot->srna, "constraint_orientation", orientation_items, V3D_MANIP_GLOBAL, "Orientation", "DOC_BROKEN");
307         RNA_def_enum_funcs(prop, select_orientation_itemf);
308 }
309
310 void TFM_OT_translate(struct wmOperatorType *ot)
311 {
312         /* identifiers */
313         ot->name   = "Translate";
314         ot->description= "Translate selected items.";
315         ot->idname = OP_TRANSLATION;
316         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
317
318         /* api callbacks */
319         ot->invoke = transform_invoke;
320         ot->exec   = transform_exec;
321         ot->modal  = transform_modal;
322         ot->cancel  = transform_cancel;
323         ot->poll   = ED_operator_areaactive;
324
325         RNA_def_float_vector(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
326
327         Properties_Proportional(ot);
328
329         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
330
331         Properties_Constraints(ot);
332
333         Properties_Snapping(ot, 1);
334 }
335
336 void TFM_OT_resize(struct wmOperatorType *ot)
337 {
338         /* identifiers */
339         ot->name   = "Resize";
340         ot->description= "Resize selected items."; 
341         ot->idname = OP_RESIZE;
342         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
343
344         /* api callbacks */
345         ot->invoke = transform_invoke;
346         ot->exec   = transform_exec;
347         ot->modal  = transform_modal;
348         ot->cancel  = transform_cancel;
349         ot->poll   = ED_operator_areaactive;
350
351         RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
352
353         Properties_Proportional(ot);
354
355         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
356
357         Properties_Constraints(ot);
358
359         Properties_Snapping(ot, 0);
360 }
361
362
363 void TFM_OT_trackball(struct wmOperatorType *ot)
364 {
365         /* identifiers */
366         ot->name   = "Trackball";
367         ot->description= "Trackball style rotation of selected items.";
368         ot->idname = OP_TRACKBALL;
369         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
370
371         /* api callbacks */
372         ot->invoke = transform_invoke;
373         ot->exec   = transform_exec;
374         ot->modal  = transform_modal;
375         ot->cancel  = transform_cancel;
376         ot->poll   = ED_operator_areaactive;
377
378         RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "angle", "", -FLT_MAX, FLT_MAX);
379
380         Properties_Proportional(ot);
381
382         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
383 }
384
385 void TFM_OT_rotate(struct wmOperatorType *ot)
386 {
387         /* identifiers */
388         ot->name   = "Rotate";
389         ot->description= "Rotate selected items.";
390         ot->idname = OP_ROTATION;
391         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
392
393         /* api callbacks */
394         ot->invoke = transform_invoke;
395         ot->exec   = transform_exec;
396         ot->modal  = transform_modal;
397         ot->cancel  = transform_cancel;
398         ot->poll   = ED_operator_areaactive;
399
400         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
401
402         Properties_Proportional(ot);
403
404         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
405
406         Properties_Constraints(ot);
407
408         Properties_Snapping(ot, 0);
409 }
410
411 void TFM_OT_tilt(struct wmOperatorType *ot)
412 {
413         /* identifiers */
414         ot->name   = "Tilt";
415     /*optionals - 
416         "Tilt selected vertices."
417         "Specify an extra axis rotation for selected vertices of 3d curve." */
418         ot->description= "Tilt selected control vertices of 3d curve."; 
419         ot->idname = OP_TILT;
420         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
421
422         /* api callbacks */
423         ot->invoke = transform_invoke;
424         ot->exec   = transform_exec;
425         ot->modal  = transform_modal;
426         ot->cancel  = transform_cancel;
427         ot->poll   = ED_operator_editcurve;
428
429         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
430
431         Properties_Proportional(ot);
432
433         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
434
435         Properties_Constraints(ot);
436 }
437
438 void TFM_OT_warp(struct wmOperatorType *ot)
439 {
440         /* identifiers */
441         ot->name   = "Warp";
442         ot->description= "Warp selected items around the cursor.";
443         ot->idname = OP_WARP;
444         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
445
446         /* api callbacks */
447         ot->invoke = transform_invoke;
448         ot->exec   = transform_exec;
449         ot->modal  = transform_modal;
450         ot->cancel  = transform_cancel;
451         ot->poll   = ED_operator_areaactive;
452
453         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", 0, 1);
454
455         Properties_Proportional(ot);
456
457         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
458
459         // XXX Shear axis?
460 //      Properties_Constraints(ot);
461 }
462
463 void TFM_OT_shear(struct wmOperatorType *ot)
464 {
465         /* identifiers */
466         ot->name   = "Shear";
467         ot->description= "Shear selected items along the horizontal screen axis.";
468         ot->idname = OP_SHEAR;
469         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
470
471         /* api callbacks */
472         ot->invoke = transform_invoke;
473         ot->exec   = transform_exec;
474         ot->modal  = transform_modal;
475         ot->cancel  = transform_cancel;
476         ot->poll   = ED_operator_areaactive;
477
478         RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
479
480         Properties_Proportional(ot);
481
482         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
483
484         // XXX Shear axis?
485 //      Properties_Constraints(ot);
486 }
487
488 void TFM_OT_shrink_fatten(struct wmOperatorType *ot)
489 {
490         /* identifiers */
491         ot->name   = "Shrink/Fatten";
492         ot->description= "Shrink/fatten selected vertices along normals.";
493         ot->idname = OP_SHRINK_FATTEN;
494         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
495
496         /* api callbacks */
497         ot->invoke = transform_invoke;
498         ot->exec   = transform_exec;
499         ot->modal  = transform_modal;
500         ot->cancel  = transform_cancel;
501         ot->poll   = ED_operator_editmesh;
502
503         RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
504
505         Properties_Proportional(ot);
506
507         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
508 }
509
510 void TFM_OT_tosphere(struct wmOperatorType *ot)
511 {
512         /* identifiers */
513         ot->name   = "To Sphere";
514     //added "around mesh center" to differentiate between "MESH_OT_vertices_to_sphere()" 
515         ot->description= "Move selected vertices outward in a spherical shape around mesh center.";
516         ot->idname = OP_TOSPHERE;
517         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
518
519         /* api callbacks */
520         ot->invoke = transform_invoke;
521         ot->exec   = transform_exec;
522         ot->modal  = transform_modal;
523         ot->cancel  = transform_cancel;
524         ot->poll   = ED_operator_areaactive;
525
526         RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1);
527
528         Properties_Proportional(ot);
529
530         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
531 }
532
533 void TFM_OT_mirror(struct wmOperatorType *ot)
534 {
535         /* identifiers */
536         ot->name   = "Mirror";
537         ot->description= "Mirror selected vertices around one or more axes.";
538         ot->idname = OP_MIRROR;
539         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
540
541         /* api callbacks */
542         ot->invoke = transform_invoke;
543         ot->exec   = transform_exec;
544         ot->modal  = transform_modal;
545         ot->cancel  = transform_cancel;
546         ot->poll   = ED_operator_areaactive;
547
548         Properties_Proportional(ot);
549         Properties_Constraints(ot);
550 }
551
552 void TFM_OT_transform(struct wmOperatorType *ot)
553 {
554         static EnumPropertyItem transform_mode_types[] = {
555                         {TFM_INIT, "INIT", 0, "Init", ""},
556                         {TFM_DUMMY, "DUMMY", 0, "Dummy", ""},
557                         {TFM_TRANSLATION, "TRANSLATION", 0, "Translation", ""},
558                         {TFM_ROTATION, "ROTATION", 0, "Rotation", ""},
559                         {TFM_RESIZE, "RESIZE", 0, "Resize", ""},
560                         {TFM_TOSPHERE, "TOSPHERE", 0, "Tosphere", ""},
561                         {TFM_SHEAR, "SHEAR", 0, "Shear", ""},
562                         {TFM_WARP, "WARP", 0, "Warp", ""},
563                         {TFM_SHRINKFATTEN, "SHRINKFATTEN", 0, "Shrinkfatten", ""},
564                         {TFM_TILT, "TILT", 0, "Tilt", ""},
565                         {TFM_TRACKBALL, "TRACKBALL", 0, "Trackball", ""},
566                         {TFM_PUSHPULL, "PUSHPULL", 0, "Pushpull", ""},
567                         {TFM_CREASE, "CREASE", 0, "Crease", ""},
568                         {TFM_MIRROR, "MIRROR", 0, "Mirror", ""},
569                         {TFM_BONESIZE, "BONESIZE", 0, "Bonesize", ""},
570                         {TFM_BONE_ENVELOPE, "BONE_ENVELOPE", 0, "Bone_Envelope", ""},
571                         {TFM_CURVE_SHRINKFATTEN, "CURVE_SHRINKFATTEN", 0, "Curve_Shrinkfatten", ""},
572                         {TFM_BONE_ROLL, "BONE_ROLL", 0, "Bone_Roll", ""},
573                         {TFM_TIME_TRANSLATE, "TIME_TRANSLATE", 0, "Time_Translate", ""},
574                         {TFM_TIME_SLIDE, "TIME_SLIDE", 0, "Time_Slide", ""},
575                         {TFM_TIME_SCALE, "TIME_SCALE", 0, "Time_Scale", ""},
576                         {TFM_TIME_EXTEND, "TIME_EXTEND", 0, "Time_Extend", ""},
577                         {TFM_BAKE_TIME, "BAKE_TIME", 0, "Bake_Time", ""},
578                         {TFM_BEVEL, "BEVEL", 0, "Bevel", ""},
579                         {TFM_BWEIGHT, "BWEIGHT", 0, "Bweight", ""},
580                         {TFM_ALIGN, "ALIGN", 0, "Align", ""},
581                         {TFM_EDGE_SLIDE, "EDGESLIDE", 0, "Edge Slide", ""},
582                         {0, NULL, 0, NULL, NULL}
583         };
584
585         /* identifiers */
586         ot->name   = "Transform";
587         ot->description= "Transform selected items by mode type.";
588         ot->idname = "TFM_OT_transform";
589         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
590
591         /* api callbacks */
592         ot->invoke = transform_invoke;
593         ot->exec   = transform_exec;
594         ot->modal  = transform_modal;
595         ot->cancel  = transform_cancel;
596         ot->poll   = ED_operator_areaactive;
597
598         RNA_def_enum(ot->srna, "mode", transform_mode_types, 0, "Mode", "");
599
600         RNA_def_float_vector(ot->srna, "value", 4, NULL, -FLT_MAX, FLT_MAX, "Values", "", -FLT_MAX, FLT_MAX);
601
602         Properties_Proportional(ot);
603         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
604
605         Properties_Constraints(ot);
606 }
607
608 void transform_operatortypes(void)
609 {
610         WM_operatortype_append(TFM_OT_transform);
611         WM_operatortype_append(TFM_OT_translate);
612         WM_operatortype_append(TFM_OT_rotate);
613         WM_operatortype_append(TFM_OT_tosphere);
614         WM_operatortype_append(TFM_OT_resize);
615         WM_operatortype_append(TFM_OT_shear);
616         WM_operatortype_append(TFM_OT_warp);
617         WM_operatortype_append(TFM_OT_shrink_fatten);
618         WM_operatortype_append(TFM_OT_tilt);
619         WM_operatortype_append(TFM_OT_trackball);
620         WM_operatortype_append(TFM_OT_mirror);
621
622         WM_operatortype_append(TFM_OT_select_orientation);
623 }
624
625 void transform_keymap_for_space(struct wmWindowManager *wm, struct wmKeyMap *keymap, int spaceid)
626 {
627         wmKeymapItem *km;
628         
629         /* transform.c, only adds modal map once, checks if it's there */
630         transform_modal_keymap(wm);
631         
632         switch(spaceid)
633         {
634                 case SPACE_VIEW3D:
635                         km = WM_keymap_add_item(keymap, "TFM_OT_translate", GKEY, KM_PRESS, 0, 0);
636
637                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
638
639                         km = WM_keymap_add_item(keymap, "TFM_OT_rotate", RKEY, KM_PRESS, 0, 0);
640
641                         km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
642
643                         km = WM_keymap_add_item(keymap, "TFM_OT_warp", WKEY, KM_PRESS, KM_SHIFT, 0);
644
645                         km = WM_keymap_add_item(keymap, "TFM_OT_tosphere", SKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
646
647                         km = WM_keymap_add_item(keymap, "TFM_OT_shear", SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
648
649                         km = WM_keymap_add_item(keymap, "TFM_OT_shrink_fatten", SKEY, KM_PRESS, KM_ALT, 0);
650
651                         km = WM_keymap_add_item(keymap, "TFM_OT_tilt", TKEY, KM_PRESS, 0, 0);
652
653                         km = WM_keymap_add_item(keymap, "TFM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0);
654
655                         break;
656                 case SPACE_ACTION:
657                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
658                         RNA_int_set(km->ptr, "mode", TFM_TIME_TRANSLATE);
659
660                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
661                         RNA_int_set(km->ptr, "mode", TFM_TIME_TRANSLATE);
662
663                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
664                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
665
666                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
667                         RNA_int_set(km->ptr, "mode", TFM_TIME_SCALE);
668
669                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", TKEY, KM_PRESS, 0, 0);
670                         RNA_int_set(km->ptr, "mode", TFM_TIME_SLIDE);
671                         break;
672                 case SPACE_IPO:
673                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", GKEY, KM_PRESS, 0, 0);
674
675                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
676
677                                 // XXX the 'mode' identifier here is not quite right
678                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
679                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
680
681                         km = WM_keymap_add_item(keymap, "TFM_OT_rotate", RKEY, KM_PRESS, 0, 0);
682
683                         km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
684                         break;
685                 case SPACE_NLA:
686                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
687                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
688                         
689                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
690                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
691                         
692                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
693                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
694                         
695                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
696                         RNA_int_set(km->ptr, "mode", TFM_TIME_SCALE);
697                         break;
698                 case SPACE_NODE:
699                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", GKEY, KM_PRESS, 0, 0);
700
701                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", EVT_TWEAK_A, KM_ANY, 0, 0);
702                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
703
704                         km = WM_keymap_add_item(keymap, "TFM_OT_rotate", RKEY, KM_PRESS, 0, 0);
705
706                         km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
707                         break;
708                 case SPACE_SEQ:
709                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", GKEY, KM_PRESS, 0, 0);
710
711                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
712
713                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
714                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
715                         break;
716                 case SPACE_IMAGE:
717                         km = WM_keymap_add_item(keymap, "TFM_OT_translate", GKEY, KM_PRESS, 0, 0);
718
719                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
720
721                         km = WM_keymap_add_item(keymap, "TFM_OT_rotate", RKEY, KM_PRESS, 0, 0);
722
723                         km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
724
725                         km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, 0, 0);
726                         break;
727                 default:
728                         break;
729         }
730 }
731