7a3f759e47158c5b70a6b113ae10a1a2692987f8
[blender-staging.git] / source / blender / editors / mask / mask_edit.c
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * The Original Code is Copyright (C) 2012 Blender Foundation.
19  * All rights reserved.
20  *
21  *
22  * Contributor(s): Blender Foundation,
23  *                 Sergey Sharybin
24  *
25  * ***** END GPL LICENSE BLOCK *****
26  */
27
28 /** \file blender/editors/mask/mask_ops.c
29  *  \ingroup edmask
30  */
31
32
33 #include "BLI_math.h"
34
35 #include "BKE_context.h"
36 #include "BKE_mask.h"
37
38 #include "WM_api.h"
39 #include "WM_types.h"
40
41 #include "ED_screen.h"
42 #include "ED_mask.h"  /* own include */
43 #include "ED_object.h" /* ED_keymap_proportional_maskmode only */
44 #include "ED_clip.h"
45 #include "ED_transform.h"
46
47 #include "RNA_access.h"
48
49 #include "mask_intern.h"  /* own include */
50
51 /********************** generic poll functions *********************/
52
53 int ED_maskediting_poll(bContext *C)
54 {
55         SpaceClip *sc = CTX_wm_space_clip(C);
56
57         if (sc) {
58                 return ED_space_clip_maskediting_poll(C);
59         }
60
61         return FALSE;
62 }
63
64 int ED_maskediting_mask_poll(bContext *C)
65 {
66         SpaceClip *sc = CTX_wm_space_clip(C);
67
68         if (sc) {
69                 return ED_space_clip_maskediting_mask_poll(C);
70         }
71
72         return FALSE;
73 }
74
75 /********************** registration *********************/
76
77 void ED_mask_mouse_pos(bContext *C, wmEvent *event, float co[2])
78 {
79         SpaceClip *sc = CTX_wm_space_clip(C);
80
81         if (sc) {
82                 ED_clip_mouse_pos(C, event, co);
83                 BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
84         }
85         else {
86                 /* possible other spaces from which mask editing is available */
87                 zero_v2(co);
88         }
89 }
90
91 /* input:  x/y   - mval space
92  * output: xr/yr - mask point space */
93 void ED_mask_point_pos(bContext *C, float x, float y, float *xr, float *yr)
94 {
95         SpaceClip *sc = CTX_wm_space_clip(C);
96         float co[2];
97
98         if (sc) {
99                 ED_clip_point_stable_pos(C, x, y, &co[0], &co[1]);
100                 BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
101         }
102         else {
103                 /* possible other spaces from which mask editing is available */
104                 zero_v2(co);
105         }
106
107         *xr = co[0];
108         *yr = co[1];
109 }
110
111 void ED_mask_point_pos__reverse(bContext *C, float x, float y, float *xr, float *yr)
112 {
113         SpaceClip *sc = CTX_wm_space_clip(C);
114         ARegion *ar = CTX_wm_region(C);
115
116         float co[2];
117
118         if (sc && ar) {
119                 co[0] = x;
120                 co[1] = y;
121                 BKE_mask_coord_to_movieclip(sc->clip, &sc->user, co, co);
122                 ED_clip_point_stable_pos__reverse(sc, ar, co, co);
123         }
124         else {
125                 /* possible other spaces from which mask editing is available */
126                 zero_v2(co);
127         }
128
129         *xr = co[0];
130         *yr = co[1];
131 }
132
133 void ED_mask_size(bContext *C, int *width, int *height)
134 {
135         SpaceClip *sc = CTX_wm_space_clip(C);
136
137         if (sc) {
138                 ED_space_clip_mask_size(sc, width, height);
139         }
140         else {
141                 /* possible other spaces from which mask editing is available */
142                 *width = 0;
143                 *height = 0;
144         }
145 }
146
147 void ED_mask_aspect(bContext *C, float *aspx, float *aspy)
148 {
149         SpaceClip *sc = CTX_wm_space_clip(C);
150
151         if (sc) {
152                 ED_space_clip_mask_aspect(sc, aspx, aspy);
153         }
154         else {
155                 /* possible other spaces from which mask editing is available */
156                 *aspx = 1.0f;
157                 *aspy = 1.0f;
158         }
159 }
160
161 void ED_mask_pixelspace_factor(bContext *C, float *scalex, float *scaley)
162 {
163         SpaceClip *sc = CTX_wm_space_clip(C);
164
165         if (sc) {
166                 ARegion *ar = CTX_wm_region(C);
167                 int width, height;
168                 float zoomx, zoomy, aspx, aspy;
169
170                 ED_space_clip_size(sc, &width, &height);
171                 ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
172                 ED_space_clip_aspect(sc, &aspx, &aspy);
173
174                 *scalex = ((float)width * aspx) * zoomx;
175                 *scaley = ((float)height * aspy) * zoomy;
176         }
177         else {
178                 /* possible other spaces from which mask editing is available */
179                 *scalex = 1.0f;
180                 *scaley = 1.0f;
181         }
182 }
183
184 /********************** registration *********************/
185
186 void ED_operatortypes_mask(void)
187 {
188         WM_operatortype_append(MASK_OT_new);
189
190         /* mask layers */
191         WM_operatortype_append(MASK_OT_layer_new);
192         WM_operatortype_append(MASK_OT_layer_remove);
193
194         /* add */
195         WM_operatortype_append(MASK_OT_add_vertex);
196         WM_operatortype_append(MASK_OT_add_feather_vertex);
197
198         /* geometry */
199         WM_operatortype_append(MASK_OT_switch_direction);
200         WM_operatortype_append(MASK_OT_delete);
201
202         /* select */
203         WM_operatortype_append(MASK_OT_select);
204         WM_operatortype_append(MASK_OT_select_all);
205         WM_operatortype_append(MASK_OT_select_border);
206         WM_operatortype_append(MASK_OT_select_lasso);
207         WM_operatortype_append(MASK_OT_select_circle);
208         WM_operatortype_append(MASK_OT_select_linked_pick);
209         WM_operatortype_append(MASK_OT_select_linked);
210
211         /* hide/reveal */
212         WM_operatortype_append(MASK_OT_hide_view_clear);
213         WM_operatortype_append(MASK_OT_hide_view_set);
214
215         /* shape */
216         WM_operatortype_append(MASK_OT_slide_point);
217         WM_operatortype_append(MASK_OT_cyclic_toggle);
218         WM_operatortype_append(MASK_OT_handle_type_set);
219
220         /* relationships */
221         WM_operatortype_append(MASK_OT_parent_set);
222         WM_operatortype_append(MASK_OT_parent_clear);
223
224         /* shapekeys */
225         WM_operatortype_append(MASK_OT_shape_key_insert);
226         WM_operatortype_append(MASK_OT_shape_key_clear);
227 }
228
229 void ED_keymap_mask(wmKeyConfig *keyconf)
230 {
231         wmKeyMap *keymap;
232         wmKeyMapItem *kmi;
233
234         keymap = WM_keymap_find(keyconf, "Mask Editing", 0, 0);
235         keymap->poll = ED_maskediting_poll;
236
237         WM_keymap_add_item(keymap, "MASK_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
238
239         /* mask mode supports PET now */
240         ED_keymap_proportional_cycle(keyconf, keymap);
241         ED_keymap_proportional_maskmode(keyconf, keymap);
242
243         /* geometry */
244         WM_keymap_add_item(keymap, "MASK_OT_add_vertex_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
245         WM_keymap_add_item(keymap, "MASK_OT_add_feather_vertex_slide", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
246         WM_keymap_add_item(keymap, "MASK_OT_delete", XKEY, KM_PRESS, 0, 0);
247         WM_keymap_add_item(keymap, "MASK_OT_delete", DELKEY, KM_PRESS, 0, 0);
248
249         /* selection */
250         kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
251         RNA_boolean_set(kmi->ptr, "extend", FALSE);
252         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
253         RNA_boolean_set(kmi->ptr, "toggle", FALSE);
254         kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
255         RNA_boolean_set(kmi->ptr, "extend", FALSE);
256         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
257         RNA_boolean_set(kmi->ptr, "toggle", TRUE);
258
259         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", AKEY, KM_PRESS, 0, 0);
260         RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
261         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
262         RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
263
264         WM_keymap_add_item(keymap, "MASK_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
265         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0);
266         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
267         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0);
268         RNA_boolean_set(kmi->ptr, "deselect", TRUE);
269
270         WM_keymap_add_item(keymap, "MASK_OT_select_border", BKEY, KM_PRESS, 0, 0);
271         WM_keymap_add_item(keymap, "MASK_OT_select_circle", CKEY, KM_PRESS, 0, 0);
272
273         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
274         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
275         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0);
276         RNA_boolean_set(kmi->ptr, "deselect", TRUE);
277
278         /* hide/reveal */
279         WM_keymap_add_item(keymap, "MASK_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
280         kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
281         RNA_boolean_set(kmi->ptr, "unselected", FALSE);
282
283         kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
284         RNA_boolean_set(kmi->ptr, "unselected", TRUE);
285
286         /* select clip while in maker view,
287          * this matches View3D functionality where you can select an
288          * object while in editmode to allow vertex parenting */
289         kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
290         RNA_boolean_set(kmi->ptr, "extend", FALSE);
291
292         /* shape */
293         WM_keymap_add_item(keymap, "MASK_OT_cyclic_toggle", CKEY, KM_PRESS, KM_ALT, 0);
294         WM_keymap_add_item(keymap, "MASK_OT_slide_point", LEFTMOUSE, KM_PRESS, 0, 0);
295         WM_keymap_add_item(keymap, "MASK_OT_handle_type_set", VKEY, KM_PRESS, 0, 0);
296
297         /* relationships */
298         WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
299         WM_keymap_add_item(keymap, "MASK_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
300
301         WM_keymap_add_item(keymap, "MASK_OT_shape_key_insert", IKEY, KM_PRESS, 0, 0);
302         WM_keymap_add_item(keymap, "MASK_OT_shape_key_clear", IKEY, KM_PRESS, KM_ALT, 0);
303
304
305         transform_keymap_for_space(keyconf, keymap, SPACE_CLIP);
306 }
307
308 void ED_operatormacros_mask(void)
309 {
310         /* XXX: just for sample */
311         wmOperatorType *ot;
312         wmOperatorTypeMacro *otmacro;
313
314         ot = WM_operatortype_append_macro("MASK_OT_add_vertex_slide", "Add Vertex and Slide", "Add new vertex and slide it", OPTYPE_UNDO | OPTYPE_REGISTER);
315         ot->description = "Add new vertex and slide it";
316         WM_operatortype_macro_define(ot, "MASK_OT_add_vertex");
317         otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
318         RNA_boolean_set(otmacro->ptr, "release_confirm", TRUE);
319
320         ot = WM_operatortype_append_macro("MASK_OT_add_feather_vertex_slide", "Add Feather Vertex and Slide", "Add new vertex to feater and slide it", OPTYPE_UNDO | OPTYPE_REGISTER);
321         ot->description = "Add new feather vertex and slide it";
322         WM_operatortype_macro_define(ot, "MASK_OT_add_feather_vertex");
323         otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point");
324         RNA_boolean_set(otmacro->ptr, "slide_feather", TRUE);
325 }