b2a865074fdd2a18f75ff39efb0254b09a0b6c22
[blender.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
29 #include "RNA_access.h"
30 #include "RNA_define.h"
31
32 #include "BLI_arithb.h"
33
34 #include "BKE_utildefines.h"
35 #include "BKE_context.h"
36
37 #include "WM_api.h"
38 #include "WM_types.h"
39
40 #include "ED_screen.h"
41
42 #include "transform.h"
43
44 static void transformops_exit(bContext *C, wmOperator *op)
45 {
46         MEM_freeN(op->customdata);
47         op->customdata = NULL;
48 }
49
50 static void transformops_data(bContext *C, wmOperator *op, wmEvent *event)
51 {
52         int mode    = RNA_int_get(op->ptr, "mode");
53         int options = RNA_int_get(op->ptr, "options");
54         TransInfo *t = MEM_callocN(sizeof(TransInfo), "TransInfo data");
55         
56         initTransform(C, t, mode, options, event);
57
58         /* store data */
59         op->customdata = t;
60 }
61
62 static int transform_modal(bContext *C, wmOperator *op, wmEvent *event)
63 {
64         TransInfo *t = op->customdata;
65
66         transformEvent(t, event);
67         
68         transformApply(t);
69         
70         if (transformEnd(t))
71         {
72                 transformops_exit(C, op);
73                 return OPERATOR_FINISHED;
74         }
75         else
76         {
77                 return OPERATOR_RUNNING_MODAL;
78         }
79 }
80
81 static int transform_exec(bContext *C, wmOperator *op)
82 {
83         TransInfo *t = op->customdata;
84         
85         transformApply(t);
86         
87         transformEnd(t);
88
89         ED_region_tag_redraw(CTX_wm_region(C));
90
91         transformops_exit(C, op);
92         
93         return OPERATOR_FINISHED;
94 }
95
96 static int transform_invoke(bContext *C, wmOperator *op, wmEvent *event)
97 {
98         float value[4];
99         
100         RNA_float_get_array(op->ptr, "value", value);
101
102         /* makes op->customdata */
103         transformops_data(C, op, event);
104
105         if(!QuatIsNul(value)) {
106                 TransInfo *t = op->customdata;
107                 
108                 VECCOPY(t->values, value); /* SHOULD BE VEC-4 */
109                 
110                 return transform_exec(C, op);
111         }
112         else {
113                 /* add temp handler */
114                 WM_event_add_modal_handler(C, &CTX_wm_window(C)->handlers, op);
115
116                 return OPERATOR_RUNNING_MODAL;
117         }
118 }
119
120 void TFM_OT_transform(struct wmOperatorType *ot)
121 {
122         PropertyRNA *prop;
123         static float value[4] = {0, 0, 0};
124         
125         /* identifiers */
126         ot->name   = "Transform";
127         ot->idname = "TFM_OT_transform";
128
129         /* api callbacks */
130         ot->invoke = transform_invoke;
131         ot->exec   = transform_exec;
132         ot->modal  = transform_modal;
133         ot->poll   = ED_operator_areaactive;
134
135         RNA_def_property(ot->srna, "mode", PROP_INT, PROP_NONE);
136         RNA_def_property(ot->srna, "options", PROP_INT, PROP_NONE);
137         
138         prop = RNA_def_property(ot->srna, "value", PROP_FLOAT, PROP_VECTOR);
139         RNA_def_property_array(prop, 4);
140         RNA_def_property_float_array_default(prop, value);
141 }
142
143 void transform_operatortypes(void)
144 {
145         WM_operatortype_append(TFM_OT_transform);
146 }
147  
148 void transform_keymap_for_space(struct wmWindowManager *wm, struct ListBase *keymap, int spaceid)
149 {
150         wmKeymapItem *km;
151         switch(spaceid)
152         {
153                 case SPACE_VIEW3D:
154                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
155                         RNA_int_set(km->ptr, "mode", TFM_TRANSLATION);
156
157                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", RKEY, KM_PRESS, 0, 0);
158                         RNA_int_set(km->ptr, "mode", TFM_ROTATION);
159
160                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
161                         RNA_int_set(km->ptr, "mode", TFM_RESIZE);
162
163                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", WKEY, KM_PRESS, KM_SHIFT, 0);
164                         RNA_int_set(km->ptr, "mode", TFM_WARP);
165
166                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, KM_CTRL|KM_SHIFT, 0);
167                         RNA_int_set(km->ptr, "mode", TFM_TOSPHERE);
168                         
169                         km = WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, KM_ALT|KM_CTRL|KM_SHIFT, 0);
170                         RNA_int_set(km->ptr, "mode", TFM_SHEAR);
171                         
172                         break;
173                 case SPACE_ACTION:
174                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", GKEY, KM_PRESS, 0, 0);
175                         RNA_int_set(km->ptr, "mode", TFM_TIME_TRANSLATE);
176                         
177                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", EKEY, KM_PRESS, 0, 0);
178                         RNA_int_set(km->ptr, "mode", TFM_TIME_EXTEND);
179                         
180                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", SKEY, KM_PRESS, 0, 0);
181                         RNA_int_set(km->ptr, "mode", TFM_TIME_SCALE);
182                         
183                         km= WM_keymap_add_item(keymap, "TFM_OT_transform", TKEY, KM_PRESS, 0, 0);
184                         RNA_int_set(km->ptr, "mode", TFM_TIME_SLIDE);
185                 default:
186                         break;
187         }
188 }