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