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