49f0020420a4df0e0c11dadf35de855827b20bd7
[blender-staging.git] / source / blender / editors / transform / transform_ops.c
1 /**
2  * $Id: transform_ops.c 17542 2008-11-23 15:27:53Z theeth $
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_space_types.h"
28 #include "DNA_windowmanager_types.h"
29
30 #include "RNA_access.h"
31 #include "RNA_define.h"
32
33 #include "BLI_arithb.h"
34
35 #include "BKE_utildefines.h"
36 #include "BKE_context.h"
37
38 #include "WM_api.h"
39 #include "WM_types.h"
40
41 #include "UI_interface.h"
42
43 #include "ED_screen.h"
44
45 #include "transform.h"
46
47 static int select_orientation_exec(bContext *C, wmOperator *op)
48 {
49         int orientation = RNA_enum_get(op->ptr, "orientation");
50         int custom_index= RNA_int_get(op->ptr, "custom_index");;
51
52         if(orientation == V3D_MANIP_CUSTOM)
53                 orientation += custom_index;
54         
55         BIF_selectTransformOrientationValue(C, orientation);
56
57         return OPERATOR_FINISHED;
58 }
59
60 static int select_orientation_invoke(bContext *C, wmOperator *op, wmEvent *event)
61 {
62         uiMenuItem *head;
63         
64         head= uiPupMenuBegin("Orientation", 0);
65         BIF_menuTransformOrientation(C, head, NULL);
66         uiPupMenuEnd(C, head);
67         
68         return OPERATOR_CANCELLED;
69 }
70         
71 void TFM_OT_select_orientation(struct wmOperatorType *ot)
72 {
73         static EnumPropertyItem orientation_items[]= {
74                 {V3D_MANIP_GLOBAL, "GLOBAL", "Global", ""},
75                 {V3D_MANIP_NORMAL, "NORMAL", "Normal", ""},
76                 {V3D_MANIP_LOCAL, "LOCAL", "Local", ""},
77                 {V3D_MANIP_VIEW, "VIEW", "View", ""},
78                 {V3D_MANIP_CUSTOM, "CUSTOM", "Custom", ""},
79                 {0, NULL, NULL, NULL}};
80
81         /* identifiers */
82         ot->name   = "Select Orientation";
83         ot->idname = "TFM_OT_select_orientation";
84
85         /* api callbacks */
86         ot->invoke = select_orientation_invoke;
87         ot->exec   = select_orientation_exec;
88         ot->poll   = ED_operator_areaactive;
89
90         RNA_def_enum(ot->srna, "orientation", orientation_items, V3D_MANIP_CUSTOM, "Orientation", "DOC_BROKEN");
91         RNA_def_int(ot->srna, "custom_index", 0, 0, INT_MAX, "Custom Index", "", 0, INT_MAX);
92 }
93
94 static void transformops_exit(bContext *C, wmOperator *op)
95 {
96         saveTransform(C, op->customdata, op);
97         MEM_freeN(op->customdata);
98         op->customdata = NULL;
99 }
100
101 static void transformops_data(bContext *C, wmOperator *op, wmEvent *event)
102 {
103         if (op->customdata == NULL)
104         {
105                 TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data");
106                 
107                 initTransform(C, t, op, event);
108         
109                 /* store data */
110                 op->customdata = t;
111         }
112 }
113
114 static int transform_modal(bContext *C, wmOperator *op, wmEvent *event)
115 {
116         int exit_code;
117         
118         TransInfo *t = op->customdata;
119         
120         transformEvent(t, event);
121         
122         transformApply(C, t);
123         
124         
125         exit_code = transformEnd(C, t);
126         
127         if (exit_code != OPERATOR_RUNNING_MODAL)
128         {
129                 transformops_exit(C, op);
130         }
131
132         return exit_code;
133 }
134
135 static int transform_cancel(bContext *C, wmOperator *op)
136 {
137         TransInfo *t = op->customdata;
138         
139         t->state = TRANS_CANCEL;
140         transformEnd(C, t);
141         transformops_exit(C, op);
142         
143         return OPERATOR_CANCELLED;
144 }
145
146 static int transform_exec(bContext *C, wmOperator *op)
147 {
148         TransInfo *t;
149
150         transformops_data(C, op, NULL);
151
152         t = op->customdata;
153
154         t->options |= CTX_AUTOCONFIRM;
155
156         transformApply(C, t);
157         
158         transformEnd(C, t);
159
160         transformops_exit(C, op);
161         
162         return OPERATOR_FINISHED;
163 }
164
165 static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
166 {
167         transformops_data(C, op, event);
168
169         if(RNA_property_is_set(op->ptr, "values")) {
170                 return transform_exec(C, op);
171         }
172         else {
173                 /* add temp handler */
174                 WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
175
176                 return OPERATOR_RUNNING_MODAL;
177         }
178 }
179
180 void TFM_OT_transform(struct wmOperatorType *ot)
181 {
182         static const float mtx[3][3] = {{1, 0, 0},{0, 1, 0},{0, 0, 1}};
183         static EnumPropertyItem transform_mode_types[] = {
184                         {TFM_INIT, "INIT", "Init", ""},
185                         {TFM_DUMMY, "DUMMY", "Dummy", ""},
186                         {TFM_TRANSLATION, "TRANSLATION", "Translation", ""},
187                         {TFM_ROTATION, "ROTATION", "Rotation", ""},
188                         {TFM_RESIZE, "RESIZE", "Resize", ""},
189                         {TFM_TOSPHERE, "TOSPHERE", "Tosphere", ""},
190                         {TFM_SHEAR, "SHEAR", "Shear", ""},
191                         {TFM_WARP, "WARP", "Warp", ""},
192                         {TFM_SHRINKFATTEN, "SHRINKFATTEN", "Shrinkfatten", ""},
193                         {TFM_TILT, "TILT", "Tilt", ""},
194                         {TFM_LAMP_ENERGY, "LAMP_ENERGY", "Lamp_Energy", ""},
195                         {TFM_TRACKBALL, "TRACKBALL", "Trackball", ""},
196                         {TFM_PUSHPULL, "PUSHPULL", "Pushpull", ""},
197                         {TFM_CREASE, "CREASE", "Crease", ""},
198                         {TFM_MIRROR, "MIRROR", "Mirror", ""},
199                         {TFM_BONESIZE, "BONESIZE", "Bonesize", ""},
200                         {TFM_BONE_ENVELOPE, "BONE_ENVELOPE", "Bone_Envelope", ""},
201                         {TFM_CURVE_SHRINKFATTEN, "CURVE_SHRINKFATTEN", "Curve_Shrinkfatten", ""},
202                         {TFM_BONE_ROLL, "BONE_ROLL", "Bone_Roll", ""},
203                         {TFM_TIME_TRANSLATE, "TIME_TRANSLATE", "Time_Translate", ""},
204                         {TFM_TIME_SLIDE, "TIME_SLIDE", "Time_Slide", ""},
205                         {TFM_TIME_SCALE, "TIME_SCALE", "Time_Scale", ""},
206                         {TFM_TIME_EXTEND, "TIME_EXTEND", "Time_Extend", ""},
207                         {TFM_BAKE_TIME, "BAKE_TIME", "Bake_Time", ""},
208                         {TFM_BEVEL, "BEVEL", "Bevel", ""},
209                         {TFM_BWEIGHT, "BWEIGHT", "Bweight", ""},
210                         {TFM_ALIGN, "ALIGN", "Align", ""},
211                         {0, NULL, NULL, NULL}
212         };
213         
214         /* identifiers */
215         ot->name   = "Transform";
216         ot->idname = "TFM_OT_transform";
217         ot->flag= OPTYPE_REGISTER|OPTYPE_UNDO;
218
219         /* api callbacks */
220         ot->invoke = transform_invoke;
221         ot->exec   = transform_exec;
222         ot->modal  = transform_modal;
223         ot->cancel  = transform_cancel;
224         ot->poll   = ED_operator_areaactive;
225
226         RNA_def_enum(ot->srna, "mode", transform_mode_types, 0, "Mode", "");
227         RNA_def_int(ot->srna, "options", 0, INT_MIN, INT_MAX, "Options", "", INT_MIN, INT_MAX);
228         
229         RNA_def_float_vector(ot->srna, "values", 4, NULL, -FLT_MAX, FLT_MAX, "Values", "", -FLT_MAX, FLT_MAX);
230
231         RNA_def_int(ot->srna, "constraint_orientation", 0, INT_MIN, INT_MAX, "Constraint Orientation", "", INT_MIN, INT_MAX);
232         RNA_def_int(ot->srna, "constraint_mode", 0, INT_MIN, INT_MAX, "Constraint Mode", "", INT_MIN, INT_MAX);
233
234         RNA_def_float_matrix(ot->srna, "constraint_matrix", 9, mtx[0], -FLT_MAX, FLT_MAX, "Constraint Matrix", "", -FLT_MAX, FLT_MAX);
235 }
236
237 void transform_operatortypes(void)
238 {
239         WM_operatortype_append(TFM_OT_transform);
240         WM_operatortype_append(TFM_OT_select_orientation);
241 }
242  
243 void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid)
244 {
245         wmKeymapItem *km;
246         switch(spaceid)
247         {
248                 case SPACE_VIEW3D:
249                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
250                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
251                         
252                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
253                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
254                         
255                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", RKEY, KM_PRESS, 0, 0);
256                         RNA_int_set(km->ptr, "mode", TFM_ROTATION);
257
258                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
259                         RNA_int_set(km->ptr, "mode", TFM_RESIZE);
260
261                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", WKEY, KM_PRESS, KM_SHIFT, 0);
262                         RNA_int_set(km->ptr, "mode", TFM_WARP);
263
264                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
265                         RNA_int_set(km->ptr, "mode", TFM_TOSPHERE);
266                         
267                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
268                         RNA_int_set(km->ptr, "mode", TFM_SHEAR);
269                         
270                         km = WM_keymap_add_item(keymap, "TFM_OT_select_orientation", SPACEKEY, KM_PRESS, KM_ALT, 0);
271
272                         break;
273                 case SPACE_ACTION:
274                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
275                         RNA_int_set(km->ptr, "mode", TFM_TIME_TRANSLATE);
276                         
277                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
278                         RNA_int_set(km->ptr, "mode", TFM_TIME_TRANSLATE);
279                         
280                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
281                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
282                         
283                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
284                         RNA_int_set(km->ptr, "mode", TFM_TIME_SCALE);
285                         
286                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", TKEY, KM_PRESS, 0, 0);
287                         RNA_int_set(km->ptr, "mode", TFM_TIME_SLIDE);
288                         break;
289                 case SPACE_IPO:
290                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
291                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
292                         
293                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
294                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
295                         
296                                 // XXX the 'mode' identifier here is not quite right
297                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
298                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
299                         
300                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", RKEY, KM_PRESS, 0, 0);
301                         RNA_int_set(km->ptr, "mode", TFM_ROTATION);
302                         
303                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
304                         RNA_int_set(km->ptr, "mode", TFM_RESIZE);
305                         break;
306                 case SPACE_NODE:
307                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
308                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
309                         
310                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_A, KM_ANY, 0, 0);
311                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
312                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
313                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
314                         
315                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", RKEY, KM_PRESS, 0, 0);
316                         RNA_int_set(km->ptr, "mode", TFM_ROTATION);
317                         
318                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
319                         RNA_int_set(km->ptr, "mode", TFM_RESIZE);
320                         break;
321                 case SPACE_SEQ:
322                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
323                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
324                         
325                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
326                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
327                         
328                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
329                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
330                         break;
331                 case SPACE_IMAGE:
332                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
333                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
334                         
335                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EVT_TWEAK_S, KM_ANY, 0, 0);
336                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
337                         
338                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", RKEY, KM_PRESS, 0, 0);
339                         RNA_int_set(km->ptr, "mode", TFM_ROTATION);
340
341                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
342                         RNA_int_set(km->ptr, "mode", TFM_RESIZE);
343
344                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", MKEY, KM_PRESS, 0, 0);
345                         RNA_int_set(km->ptr, "mode", TFM_MIRROR);
346                         break;
347                 default:
348                         break;
349         }
350 }
351