mask editing
[blender.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_maskedit_poll(bContext *C)
54 {
55         SpaceClip *sc = CTX_wm_space_clip(C);
56
57         if (sc) {
58                 return ED_space_clip_maskedit_poll(C);
59         }
60
61         return FALSE;
62 }
63
64 int ED_maskedit_mask_poll(bContext *C)
65 {
66         SpaceClip *sc = CTX_wm_space_clip(C);
67
68         if (sc) {
69                 return ED_space_clip_maskedit_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         /* feather */
216         WM_operatortype_append(MASK_OT_feather_weight_clear);
217
218         /* shape */
219         WM_operatortype_append(MASK_OT_slide_point);
220         WM_operatortype_append(MASK_OT_cyclic_toggle);
221         WM_operatortype_append(MASK_OT_handle_type_set);
222
223         /* relationships */
224         WM_operatortype_append(MASK_OT_parent_set);
225         WM_operatortype_append(MASK_OT_parent_clear);
226
227         /* shapekeys */
228         WM_operatortype_append(MASK_OT_shape_key_insert);
229         WM_operatortype_append(MASK_OT_shape_key_clear);
230 }
231
232 void ED_keymap_mask(wmKeyConfig *keyconf)
233 {
234         wmKeyMap *keymap;
235         wmKeyMapItem *kmi;
236
237         keymap = WM_keymap_find(keyconf, "Mask Editing", 0, 0);
238         keymap->poll = ED_maskedit_poll;
239
240         WM_keymap_add_item(keymap, "MASK_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
241
242         /* mask mode supports PET now */
243         ED_keymap_proportional_cycle(keyconf, keymap);
244         ED_keymap_proportional_maskmode(keyconf, keymap);
245
246         /* geometry */
247         WM_keymap_add_item(keymap, "MASK_OT_add_vertex_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
248         WM_keymap_add_item(keymap, "MASK_OT_add_feather_vertex_slide", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
249         WM_keymap_add_item(keymap, "MASK_OT_delete", XKEY, KM_PRESS, 0, 0);
250         WM_keymap_add_item(keymap, "MASK_OT_delete", DELKEY, KM_PRESS, 0, 0);
251
252         /* selection */
253         kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
254         RNA_boolean_set(kmi->ptr, "extend", FALSE);
255         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
256         RNA_boolean_set(kmi->ptr, "toggle", FALSE);
257         kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
258         RNA_boolean_set(kmi->ptr, "extend", FALSE);
259         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
260         RNA_boolean_set(kmi->ptr, "toggle", TRUE);
261
262         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", AKEY, KM_PRESS, 0, 0);
263         RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
264         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
265         RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
266
267         WM_keymap_add_item(keymap, "MASK_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
268         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0);
269         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
270         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0);
271         RNA_boolean_set(kmi->ptr, "deselect", TRUE);
272
273         WM_keymap_add_item(keymap, "MASK_OT_select_border", BKEY, KM_PRESS, 0, 0);
274         WM_keymap_add_item(keymap, "MASK_OT_select_circle", CKEY, KM_PRESS, 0, 0);
275
276         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
277         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
278         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0);
279         RNA_boolean_set(kmi->ptr, "deselect", TRUE);
280
281         /* hide/reveal */
282         WM_keymap_add_item(keymap, "MASK_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
283         kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
284         RNA_boolean_set(kmi->ptr, "unselected", FALSE);
285
286         kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
287         RNA_boolean_set(kmi->ptr, "unselected", TRUE);
288
289         /* select clip while in maker view,
290          * this matches View3D functionality where you can select an
291          * object while in editmode to allow vertex parenting */
292         kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
293         RNA_boolean_set(kmi->ptr, "extend", FALSE);
294
295         /* shape */
296         WM_keymap_add_item(keymap, "MASK_OT_cyclic_toggle", CKEY, KM_PRESS, KM_ALT, 0);
297         WM_keymap_add_item(keymap, "MASK_OT_slide_point", LEFTMOUSE, KM_PRESS, 0, 0);
298         WM_keymap_add_item(keymap, "MASK_OT_handle_type_set", VKEY, KM_PRESS, 0, 0);
299         WM_keymap_add_item(keymap, "MASK_OT_feather_weight_clear", SKEY, KM_PRESS, KM_ALT, 0);
300
301         /* relationships */
302         WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
303         WM_keymap_add_item(keymap, "MASK_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
304
305         WM_keymap_add_item(keymap, "MASK_OT_shape_key_insert", IKEY, KM_PRESS, 0, 0);
306         WM_keymap_add_item(keymap, "MASK_OT_shape_key_clear", IKEY, KM_PRESS, KM_ALT, 0);
307
308
309         transform_keymap_for_space(keyconf, keymap, SPACE_CLIP);
310 }
311
312 void ED_operatormacros_mask(void)
313 {
314         /* XXX: just for sample */
315         wmOperatorType *ot;
316         wmOperatorTypeMacro *otmacro;
317
318         ot = WM_operatortype_append_macro("MASK_OT_add_vertex_slide", "Add Vertex and Slide", "Add new vertex and slide it", OPTYPE_UNDO | OPTYPE_REGISTER);
319         ot->description = "Add new vertex and slide it";
320         WM_operatortype_macro_define(ot, "MASK_OT_add_vertex");
321         otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
322         RNA_boolean_set(otmacro->ptr, "release_confirm", TRUE);
323
324         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);
325         ot->description = "Add new feather vertex and slide it";
326         WM_operatortype_macro_define(ot, "MASK_OT_add_feather_vertex");
327         otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point");
328         RNA_boolean_set(otmacro->ptr, "slide_feather", TRUE);
329 }