- Identify and use retopo icon from icons image.
[blender-staging.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 char OP_TRANSLATION[] = "TFM_OT_translate";
59 char OP_ROTATION[] = "TFM_OT_rotate";
60 char OP_TOSPHERE[] = "TFM_OT_tosphere";
61 char OP_RESIZE[] = "TFM_OT_resize";
62 char OP_SHEAR[] = "TFM_OT_shear";
63 char OP_WARP[] = "TFM_OT_warp";
64 char OP_SHRINK_FATTEN[] = "TFM_OT_shrink_fatten";
65 char OP_TILT[] = "TFM_OT_tilt";
66 char OP_TRACKBALL[] = "TFM_OT_trackball";
67 char OP_MIRROR[] = "TFM_OT_mirror";
68 char OP_EDGE_SLIDE[] = "TFM_OT_edge_slide";
69
70
71 TransformModeItem transform_modes[] =
72 {
73         {OP_TRANSLATION, TFM_TRANSLATION},
74         {OP_ROTATION, TFM_ROTATION},
75         {OP_TOSPHERE, TFM_TOSPHERE},
76         {OP_RESIZE, TFM_RESIZE},
77         {OP_SHEAR, TFM_SHEAR},
78         {OP_WARP, TFM_WARP},
79         {OP_SHRINK_FATTEN, TFM_SHRINKFATTEN},
80         {OP_TILT, TFM_TILT},
81         {OP_TRACKBALL, TFM_TRACKBALL},
82         {OP_MIRROR, TFM_MIRROR},
83         {OP_EDGE_SLIDE, TFM_EDGE_SLIDE},
84         {NULL, 0}
85 };
86
87 static int select_orientation_exec(bContext *C, wmOperator *op)
88 {
89         int orientation = RNA_enum_get(op->ptr, "orientation");
90
91         BIF_selectTransformOrientationValue(C, orientation);
92         
93         WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
94
95         return OPERATOR_FINISHED;
96 }
97
98 static int select_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event)
99 {
100         uiPopupMenu *pup;
101         uiLayout *layout;
102
103         pup= uiPupMenuBegin(C, "Orientation", 0);
104         layout= uiPupMenuLayout(pup);
105         uiItemsEnumO(layout, "TFM_OT_select_orientation", "orientation");
106         uiPupMenuEnd(C, pup);
107
108         return OPERATOR_CANCELLED;
109 }
110
111 void TFM_OT_select_orientation(struct wmOperatorType *ot)
112 {
113         PropertyRNA *prop;
114
115         /* identifiers */
116         ot->name   = "Select Orientation";
117         ot->description= "Select transformation orientation.";
118         ot->idname = "TFM_OT_select_orientation";
119         ot->flag   = OPTYPE_UNDO;
120
121         /* api callbacks */
122         ot->invoke = select_orientation_invoke;
123         ot->exec   = select_orientation_exec;
124         ot->poll   = ED_operator_areaactive;
125
126         prop= RNA_def_property(ot->srna, "orientation", PROP_ENUM, PROP_NONE);
127         RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation.");
128         RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
129 }
130
131
132 static int delete_orientation_exec(bContext *C, wmOperator *op)
133 {
134         View3D *v3d = CTX_wm_view3d(C);
135         int selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
136
137         BIF_removeTransformOrientationIndex(C, selected_index);
138         
139         WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
140
141         return OPERATOR_FINISHED;
142 }
143
144 static int delete_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event)
145 {
146         return delete_orientation_exec(C, op);
147 }
148
149 static int delete_orientation_poll(bContext *C)
150 {
151         int selected_index = -1;
152         View3D *v3d = CTX_wm_view3d(C);
153         
154         if (ED_operator_areaactive(C) == 0)
155                 return 0;
156         
157         
158         if(v3d) {
159                 selected_index = (v3d->twmode - V3D_MANIP_CUSTOM);
160         }
161         
162         return selected_index >= 0;
163 }
164
165 void TFM_OT_delete_orientation(struct wmOperatorType *ot)
166 {
167         /* identifiers */
168         ot->name   = "Delete Orientation";
169         ot->description= "Delete transformation orientation.";
170         ot->idname = "TFM_OT_delete_orientation";
171         ot->flag   = OPTYPE_UNDO;
172
173         /* api callbacks */
174         ot->invoke = delete_orientation_invoke;
175         ot->exec   = delete_orientation_exec;
176         ot->poll   = delete_orientation_poll;
177 }
178
179 static int create_orientation_exec(bContext *C, wmOperator *op)
180 {
181         char name[36];
182         int use = RNA_boolean_get(op->ptr, "use");
183         int overwrite = RNA_boolean_get(op->ptr, "overwrite");
184         
185         RNA_string_get(op->ptr, "name", name);
186
187         BIF_createTransformOrientation(C, op->reports, name, use, overwrite);
188
189         WM_event_add_notifier(C, NC_SPACE|ND_SPACE_VIEW3D, CTX_wm_view3d(C));
190         
191         return OPERATOR_FINISHED;
192 }
193
194 static int create_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event)
195 {
196         return create_orientation_exec(C, op);
197 }
198
199 void TFM_OT_create_orientation(struct wmOperatorType *ot)
200 {
201         /* identifiers */
202         ot->name   = "Create Orientation";
203         ot->description= "Create transformation orientation from selection.";
204         ot->idname = "TFM_OT_create_orientation";
205         ot->flag   = OPTYPE_REGISTER|OPTYPE_UNDO;
206
207         /* api callbacks */
208         ot->invoke = create_orientation_invoke;
209         ot->exec   = create_orientation_exec;
210         ot->poll   = ED_operator_areaactive;
211         ot->flag   = OPTYPE_REGISTER|OPTYPE_UNDO;
212
213         RNA_def_string(ot->srna, "name", "", 35, "Name", "Text to insert at the cursor position.");
214         RNA_def_boolean(ot->srna, "use", 0, "Use after creation", "Select orientation after its creation");
215         RNA_def_boolean(ot->srna, "overwrite", 0, "Overwrite previous", "Overwrite previously created orientation with same name");
216 }
217
218 static void transformops_exit(bContext *C, wmOperator *op)
219 {
220         saveTransform(C, op->customdata, op);
221         MEM_freeN(op->customdata);
222         op->customdata = NULL;
223         G.moving = 0;
224 }
225
226 static int transformops_data(bContext *C, wmOperator *op, wmEvent *event)
227 {
228         int retval = 1;
229         if (op->customdata == NULL)
230         {
231                 TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data");
232                 TransformModeItem *tmode;
233                 int mode = -1;
234
235                 for (tmode = transform_modes; tmode->idname; tmode++)
236                 {
237                         if (op->type->idname == tmode->idname)
238                         {
239                                 mode = tmode->mode;
240                         }
241                 }
242
243                 if (mode == -1)
244                 {
245                         mode = RNA_int_get(op->ptr, "mode");
246                 }
247
248                 retval = initTransform(C, t, op, event, mode);
249                 G.moving = 1;
250
251                 /* store data */
252                 op->customdata = t;
253         }
254
255         return retval; /* return 0 on error */
256 }
257
258 static int transform_modal(bContext *C, wmOperator *op, wmEvent *event)
259 {
260         int exit_code;
261
262         TransInfo *t = op->customdata;
263
264         transformEvent(t, event);
265
266         transformApply(C, t);
267
268
269         exit_code = transformEnd(C, t);
270
271         if (exit_code != OPERATOR_RUNNING_MODAL)
272         {
273                 transformops_exit(C, op);
274         }
275
276         return exit_code;
277 }
278
279 static int transform_cancel(bContext *C, wmOperator *op)
280 {
281         TransInfo *t = op->customdata;
282
283         t->state = TRANS_CANCEL;
284         transformEnd(C, t);
285         transformops_exit(C, op);
286
287         return OPERATOR_CANCELLED;
288 }
289
290 static int transform_exec(bContext *C, wmOperator *op)
291 {
292         TransInfo *t;
293
294         if (!transformops_data(C, op, NULL))
295         {
296                 return OPERATOR_CANCELLED;
297         }
298
299         t = op->customdata;
300
301         t->options |= CTX_AUTOCONFIRM;
302
303         transformApply(C, t);
304
305         transformEnd(C, t);
306
307         transformops_exit(C, op);
308
309         return OPERATOR_FINISHED;
310 }
311
312 static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
313 {
314         if (!transformops_data(C, op, event))
315         {
316                 return OPERATOR_CANCELLED;
317         }
318
319         if(RNA_property_is_set(op->ptr, "value")) {
320                 return transform_exec(C, op);
321         }
322         else {
323                 TransInfo *t = op->customdata;
324
325                 /* add temp handler */
326                 WM_event_add_modal_handler(C, op);
327
328                 t->flag |= T_MODAL; // XXX meh maybe somewhere else
329
330                 return OPERATOR_RUNNING_MODAL;
331         }
332 }
333
334 void Properties_Proportional(struct wmOperatorType *ot)
335 {
336         RNA_def_enum(ot->srna, "proportional", proportional_editing_items, 0, "Proportional Editing", "");
337         RNA_def_enum(ot->srna, "proportional_editing_falloff", proportional_falloff_items, 0, "Proportional Editing Falloff", "Falloff type for proportional editing mode.");
338         RNA_def_float(ot->srna, "proportional_size", 1, 0, FLT_MAX, "Proportional Size", "", 0, 100);
339 }
340
341 void Properties_Snapping(struct wmOperatorType *ot, short align)
342 {
343         RNA_def_boolean(ot->srna, "snap", 0, "Snap to Point", "");
344         RNA_def_enum(ot->srna, "snap_mode", snap_mode_items, 0, "Mode", "");
345         RNA_def_float_vector(ot->srna, "snap_point", 3, NULL, -FLT_MAX, FLT_MAX, "Point", "", -FLT_MAX, FLT_MAX);
346
347         if (align)
348         {
349                 RNA_def_boolean(ot->srna, "snap_align", 0, "Align with Point Normal", "");
350                 RNA_def_float_vector(ot->srna, "snap_normal", 3, NULL, -FLT_MAX, FLT_MAX, "Normal", "", -FLT_MAX, FLT_MAX);
351         }
352 }
353
354 void Properties_Constraints(struct wmOperatorType *ot)
355 {
356         PropertyRNA *prop;
357
358         RNA_def_boolean_vector(ot->srna, "constraint_axis", 3, NULL, "Constraint Axis", "");
359         prop= RNA_def_property(ot->srna, "constraint_orientation", PROP_ENUM, PROP_NONE);
360         RNA_def_property_ui_text(prop, "Orientation", "Transformation orientation.");
361         RNA_def_enum_funcs(prop, rna_TransformOrientation_itemf);
362 }
363
364 void TFM_OT_translate(struct wmOperatorType *ot)
365 {
366         /* identifiers */
367         ot->name   = "Translate";
368         ot->description= "Translate selected items.";
369         ot->idname = OP_TRANSLATION;
370         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
371
372         /* api callbacks */
373         ot->invoke = transform_invoke;
374         ot->exec   = transform_exec;
375         ot->modal  = transform_modal;
376         ot->cancel  = transform_cancel;
377         ot->poll   = ED_operator_areaactive;
378
379         RNA_def_float_vector(ot->srna, "value", 3, NULL, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
380
381         Properties_Proportional(ot);
382
383         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
384
385         Properties_Constraints(ot);
386
387         Properties_Snapping(ot, 1);
388 }
389
390 void TFM_OT_resize(struct wmOperatorType *ot)
391 {
392         /* identifiers */
393         ot->name   = "Resize";
394         ot->description= "Resize selected items."; 
395         ot->idname = OP_RESIZE;
396         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
397
398         /* api callbacks */
399         ot->invoke = transform_invoke;
400         ot->exec   = transform_exec;
401         ot->modal  = transform_modal;
402         ot->cancel  = transform_cancel;
403         ot->poll   = ED_operator_areaactive;
404
405         RNA_def_float_vector(ot->srna, "value", 3, VecOne, -FLT_MAX, FLT_MAX, "Vector", "", -FLT_MAX, FLT_MAX);
406
407         Properties_Proportional(ot);
408
409         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
410
411         Properties_Constraints(ot);
412
413         Properties_Snapping(ot, 0);
414 }
415
416
417 void TFM_OT_trackball(struct wmOperatorType *ot)
418 {
419         /* identifiers */
420         ot->name   = "Trackball";
421         ot->description= "Trackball style rotation of selected items.";
422         ot->idname = OP_TRACKBALL;
423         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
424
425         /* api callbacks */
426         ot->invoke = transform_invoke;
427         ot->exec   = transform_exec;
428         ot->modal  = transform_modal;
429         ot->cancel  = transform_cancel;
430         ot->poll   = ED_operator_areaactive;
431
432         RNA_def_float_vector(ot->srna, "value", 2, VecOne, -FLT_MAX, FLT_MAX, "angle", "", -FLT_MAX, FLT_MAX);
433
434         Properties_Proportional(ot);
435
436         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
437 }
438
439 void TFM_OT_rotate(struct wmOperatorType *ot)
440 {
441         /* identifiers */
442         ot->name   = "Rotate";
443         ot->description= "Rotate selected items.";
444         ot->idname = OP_ROTATION;
445         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
446
447         /* api callbacks */
448         ot->invoke = transform_invoke;
449         ot->exec   = transform_exec;
450         ot->modal  = transform_modal;
451         ot->cancel  = transform_cancel;
452         ot->poll   = ED_operator_areaactive;
453
454         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
455
456         Properties_Proportional(ot);
457
458         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
459
460         Properties_Constraints(ot);
461
462         Properties_Snapping(ot, 0);
463 }
464
465 void TFM_OT_tilt(struct wmOperatorType *ot)
466 {
467         /* identifiers */
468         ot->name   = "Tilt";
469     /*optionals - 
470         "Tilt selected vertices."
471         "Specify an extra axis rotation for selected vertices of 3d curve." */
472         ot->description= "Tilt selected control vertices of 3d curve."; 
473         ot->idname = OP_TILT;
474         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
475
476         /* api callbacks */
477         ot->invoke = transform_invoke;
478         ot->exec   = transform_exec;
479         ot->modal  = transform_modal;
480         ot->cancel  = transform_cancel;
481         ot->poll   = ED_operator_editcurve;
482
483         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", -M_PI*2, M_PI*2);
484
485         Properties_Proportional(ot);
486
487         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
488
489         Properties_Constraints(ot);
490 }
491
492 void TFM_OT_warp(struct wmOperatorType *ot)
493 {
494         /* identifiers */
495         ot->name   = "Warp";
496         ot->description= "Warp selected items around the cursor.";
497         ot->idname = OP_WARP;
498         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
499
500         /* api callbacks */
501         ot->invoke = transform_invoke;
502         ot->exec   = transform_exec;
503         ot->modal  = transform_modal;
504         ot->cancel  = transform_cancel;
505         ot->poll   = ED_operator_areaactive;
506
507         RNA_def_float_rotation(ot->srna, "value", 1, NULL, -FLT_MAX, FLT_MAX, "Angle", "", 0, 1);
508
509         Properties_Proportional(ot);
510
511         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
512
513         // XXX Shear axis?
514 //      Properties_Constraints(ot);
515 }
516
517 void TFM_OT_shear(struct wmOperatorType *ot)
518 {
519         /* identifiers */
520         ot->name   = "Shear";
521         ot->description= "Shear selected items along the horizontal screen axis.";
522         ot->idname = OP_SHEAR;
523         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
524
525         /* api callbacks */
526         ot->invoke = transform_invoke;
527         ot->exec   = transform_exec;
528         ot->modal  = transform_modal;
529         ot->cancel  = transform_cancel;
530         ot->poll   = ED_operator_areaactive;
531
532         RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
533
534         Properties_Proportional(ot);
535
536         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
537
538         // XXX Shear axis?
539 //      Properties_Constraints(ot);
540 }
541
542 void TFM_OT_shrink_fatten(struct wmOperatorType *ot)
543 {
544         /* identifiers */
545         ot->name   = "Shrink/Fatten";
546         ot->description= "Shrink/fatten selected vertices along normals.";
547         ot->idname = OP_SHRINK_FATTEN;
548         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
549
550         /* api callbacks */
551         ot->invoke = transform_invoke;
552         ot->exec   = transform_exec;
553         ot->modal  = transform_modal;
554         ot->cancel  = transform_cancel;
555         ot->poll   = ED_operator_editmesh;
556
557         RNA_def_float(ot->srna, "value", 0, -FLT_MAX, FLT_MAX, "Offset", "", -FLT_MAX, FLT_MAX);
558
559         Properties_Proportional(ot);
560
561         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
562 }
563
564 void TFM_OT_tosphere(struct wmOperatorType *ot)
565 {
566         /* identifiers */
567         ot->name   = "To Sphere";
568     //added "around mesh center" to differentiate between "MESH_OT_vertices_to_sphere()" 
569         ot->description= "Move selected vertices outward in a spherical shape around mesh center.";
570         ot->idname = OP_TOSPHERE;
571         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
572
573         /* api callbacks */
574         ot->invoke = transform_invoke;
575         ot->exec   = transform_exec;
576         ot->modal  = transform_modal;
577         ot->cancel  = transform_cancel;
578         ot->poll   = ED_operator_areaactive;
579
580         RNA_def_float_factor(ot->srna, "value", 0, 0, 1, "Factor", "", 0, 1);
581
582         Properties_Proportional(ot);
583
584         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
585 }
586
587 void TFM_OT_mirror(struct wmOperatorType *ot)
588 {
589         /* identifiers */
590         ot->name   = "Mirror";
591         ot->description= "Mirror selected vertices around one or more axes.";
592         ot->idname = OP_MIRROR;
593         ot->flag = OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
594
595         /* api callbacks */
596         ot->invoke = transform_invoke;
597         ot->exec   = transform_exec;
598         ot->modal  = transform_modal;
599         ot->cancel  = transform_cancel;
600         ot->poll   = ED_operator_areaactive;
601
602         Properties_Proportional(ot);
603         Properties_Constraints(ot);
604 }
605
606 void TFM_OT_edge_slide(struct wmOperatorType *ot)
607 {
608         /* identifiers */
609         ot->name   = "Edge Slide";
610         ot->description= "Slide an edge loop along a mesh."; 
611         ot->idname = OP_EDGE_SLIDE;
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_editmesh;
620
621         RNA_def_float_factor(ot->srna, "value", 0, -1.0f, 1.0f, "Factor", "", -1.0f, 1.0f);
622
623         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
624 }
625
626 void TFM_OT_transform(struct wmOperatorType *ot)
627 {
628         static EnumPropertyItem transform_mode_types[] = {
629                         {TFM_INIT, "INIT", 0, "Init", ""},
630                         {TFM_DUMMY, "DUMMY", 0, "Dummy", ""},
631                         {TFM_TRANSLATION, "TRANSLATION", 0, "Translation", ""},
632                         {TFM_ROTATION, "ROTATION", 0, "Rotation", ""},
633                         {TFM_RESIZE, "RESIZE", 0, "Resize", ""},
634                         {TFM_TOSPHERE, "TOSPHERE", 0, "Tosphere", ""},
635                         {TFM_SHEAR, "SHEAR", 0, "Shear", ""},
636                         {TFM_WARP, "WARP", 0, "Warp", ""},
637                         {TFM_SHRINKFATTEN, "SHRINKFATTEN", 0, "Shrinkfatten", ""},
638                         {TFM_TILT, "TILT", 0, "Tilt", ""},
639                         {TFM_TRACKBALL, "TRACKBALL", 0, "Trackball", ""},
640                         {TFM_PUSHPULL, "PUSHPULL", 0, "Pushpull", ""},
641                         {TFM_CREASE, "CREASE", 0, "Crease", ""},
642                         {TFM_MIRROR, "MIRROR", 0, "Mirror", ""},
643                         {TFM_BONESIZE, "BONESIZE", 0, "Bonesize", ""},
644                         {TFM_BONE_ENVELOPE, "BONE_ENVELOPE", 0, "Bone_Envelope", ""},
645                         {TFM_CURVE_SHRINKFATTEN, "CURVE_SHRINKFATTEN", 0, "Curve_Shrinkfatten", ""},
646                         {TFM_BONE_ROLL, "BONE_ROLL", 0, "Bone_Roll", ""},
647                         {TFM_TIME_TRANSLATE, "TIME_TRANSLATE", 0, "Time_Translate", ""},
648                         {TFM_TIME_SLIDE, "TIME_SLIDE", 0, "Time_Slide", ""},
649                         {TFM_TIME_SCALE, "TIME_SCALE", 0, "Time_Scale", ""},
650                         {TFM_TIME_EXTEND, "TIME_EXTEND", 0, "Time_Extend", ""},
651                         {TFM_BAKE_TIME, "BAKE_TIME", 0, "Bake_Time", ""},
652                         {TFM_BEVEL, "BEVEL", 0, "Bevel", ""},
653                         {TFM_BWEIGHT, "BWEIGHT", 0, "Bweight", ""},
654                         {TFM_ALIGN, "ALIGN", 0, "Align", ""},
655                         {TFM_EDGE_SLIDE, "EDGESLIDE", 0, "Edge Slide", ""},
656                         {0, NULL, 0, NULL, NULL}
657         };
658
659         /* identifiers */
660         ot->name   = "Transform";
661         ot->description= "Transform selected items by mode type.";
662         ot->idname = "TFM_OT_transform";
663         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO|OPTYPE_BLOCKING;
664
665         /* api callbacks */
666         ot->invoke = transform_invoke;
667         ot->exec   = transform_exec;
668         ot->modal  = transform_modal;
669         ot->cancel  = transform_cancel;
670         ot->poll   = ED_operator_areaactive;
671
672         RNA_def_enum(ot->srna, "mode", transform_mode_types, 0, "Mode", "");
673
674         RNA_def_float_vector(ot->srna, "value", 4, NULL, -FLT_MAX, FLT_MAX, "Values", "", -FLT_MAX, FLT_MAX);
675
676         Properties_Proportional(ot);
677         RNA_def_boolean(ot->srna, "mirror", 0, "Mirror Editing", "");
678
679         Properties_Constraints(ot);
680 }
681
682 void transform_operatortypes(void)
683 {
684         WM_operatortype_append(TFM_OT_transform);
685         WM_operatortype_append(TFM_OT_translate);
686         WM_operatortype_append(TFM_OT_rotate);
687         WM_operatortype_append(TFM_OT_tosphere);
688         WM_operatortype_append(TFM_OT_resize);
689         WM_operatortype_append(TFM_OT_shear);
690         WM_operatortype_append(TFM_OT_warp);
691         WM_operatortype_append(TFM_OT_shrink_fatten);
692         WM_operatortype_append(TFM_OT_tilt);
693         WM_operatortype_append(TFM_OT_trackball);
694         WM_operatortype_append(TFM_OT_mirror);
695         WM_operatortype_append(TFM_OT_edge_slide);
696
697         WM_operatortype_append(TFM_OT_select_orientation);
698         WM_operatortype_append(TFM_OT_create_orientation);
699         WM_operatortype_append(TFM_OT_delete_orientation);
700 }
701
702 void transform_keymap_for_space(struct wmKeyConfig *keyconf, struct wmKeyMap *keymap, int spaceid)
703 {
704         wmKeyMapItem *km;
705         
706         /* transform.c, only adds modal map once, checks if it's there */
707         transform_modal_keymap(keyconf);
708         
709         switch(spaceid)
710         {
711                 case SPACE_VIEW3D:
712                         km = WM_keymap_add_item(keymap, "TFM_OT_translate", GKEY, KM_PRESS, 0, 0);
713
714                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
715
716                         km = WM_keymap_add_item(keymap, "TFM_OT_rotate", RKEY, KM_PRESS, 0, 0);
717
718                         km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
719
720                         km = WM_keymap_add_item(keymap, "TFM_OT_warp", WKEY, KM_PRESS, KM_SHIFT, 0);
721
722                         km = WM_keymap_add_item(keymap, "TFM_OT_tosphere", SKEY, KM_PRESS, KM_ALT|KM_SHIFT, 0);
723
724                         km = WM_keymap_add_item(keymap, "TFM_OT_shear", SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
725
726                         km = WM_keymap_add_item(keymap, "TFM_OT_shrink_fatten", SKEY, KM_PRESS, KM_ALT, 0);
727
728                         km = WM_keymap_add_item(keymap, "TFM_OT_tilt", TKEY, KM_PRESS, 0, 0);
729
730                         km = WM_keymap_add_item(keymap, "TFM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0);
731
732                         km = WM_keymap_add_item(keymap, "TFM_OT_create_orientation", SPACEKEY, KM_PRESS, KM_CTRL|KM_ALT, 0);
733                         RNA_boolean_set(km->ptr, "use", 1);
734
735                         km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0);
736
737                         break;
738                 case SPACE_ACTION:
739                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
740                         RNA_int_set(km->ptr, "mode", TFM_TIME_TRANSLATE);
741
742                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
743                         RNA_int_set(km->ptr, "mode", TFM_TIME_TRANSLATE);
744
745                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
746                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
747
748                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
749                         RNA_int_set(km->ptr, "mode", TFM_TIME_SCALE);
750
751                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", TKEY, KM_PRESS, 0, 0);
752                         RNA_int_set(km->ptr, "mode", TFM_TIME_SLIDE);
753                         break;
754                 case SPACE_IPO:
755                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", GKEY, KM_PRESS, 0, 0);
756
757                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
758
759                                 // XXX the 'mode' identifier here is not quite right
760                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
761                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
762
763                         km = WM_keymap_add_item(keymap, "TFM_OT_rotate", RKEY, KM_PRESS, 0, 0);
764
765                         km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
766                         break;
767                 case SPACE_NLA:
768                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
769                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
770                         
771                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
772                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
773                         
774                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
775                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
776                         
777                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
778                         RNA_int_set(km->ptr, "mode", TFM_TIME_SCALE);
779                         break;
780                 case SPACE_NODE:
781                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", GKEY, KM_PRESS, 0, 0);
782
783                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", EVT_TWEAK_A, KM_ANY, 0, 0);
784                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
785
786                         km = WM_keymap_add_item(keymap, "TFM_OT_rotate", RKEY, KM_PRESS, 0, 0);
787
788                         km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
789                         break;
790                 case SPACE_SEQ:
791                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", GKEY, KM_PRESS, 0, 0);
792
793                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
794
795                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
796                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
797                         break;
798                 case SPACE_IMAGE:
799                         km = WM_keymap_add_item(keymap, "TFM_OT_translate", GKEY, KM_PRESS, 0, 0);
800
801                         km= WM_keymap_add_item(keymap, "TFM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
802
803                         km = WM_keymap_add_item(keymap, "TFM_OT_rotate", RKEY, KM_PRESS, 0, 0);
804
805                         km = WM_keymap_add_item(keymap, "TFM_OT_resize", SKEY, KM_PRESS, 0, 0);
806
807                         km = WM_keymap_add_item(keymap, "TFM_OT_mirror", MKEY, KM_PRESS, KM_CTRL, 0);
808                         break;
809                 default:
810                         break;
811         }
812 }
813