code cleanup: pass mouse position as int[2] rather then wmEvent
[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_edit.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 "DNA_scene_types.h"
39
40 #include "WM_api.h"
41 #include "WM_types.h"
42
43 #include "ED_screen.h"
44 #include "ED_mask.h"  /* own include */
45 #include "ED_image.h"
46 #include "ED_object.h" /* ED_keymap_proportional_maskmode only */
47 #include "ED_clip.h"
48 #include "ED_sequencer.h"
49 #include "ED_transform.h"
50
51 #include "UI_view2d.h"
52
53 #include "RNA_access.h"
54
55 #include "mask_intern.h"  /* own include */
56
57 /********************** generic poll functions *********************/
58
59 int ED_maskedit_poll(bContext *C)
60 {
61         ScrArea *sa = CTX_wm_area(C);
62         if (sa) {
63                 switch (sa->spacetype) {
64                         case SPACE_CLIP:
65                                 return ED_space_clip_maskedit_poll(C);
66                         case SPACE_SEQ:
67                                 return ED_space_sequencer_maskedit_poll(C);
68                         case SPACE_IMAGE:
69                                 return ED_space_image_maskedit_poll(C);
70                 }
71         }
72         return FALSE;
73 }
74
75 int ED_maskedit_mask_poll(bContext *C)
76 {
77         ScrArea *sa = CTX_wm_area(C);
78         if (sa) {
79                 switch (sa->spacetype) {
80                         case SPACE_CLIP:
81                                 return ED_space_clip_maskedit_mask_poll(C);
82                         case SPACE_SEQ:
83                                 return ED_space_sequencer_maskedit_mask_poll(C);
84                         case SPACE_IMAGE:
85                                 return ED_space_image_maskedit_mask_poll(C);
86                 }
87         }
88         return FALSE;
89 }
90
91 /********************** registration *********************/
92
93 /* takes event->mval */
94 void ED_mask_mouse_pos(ScrArea *sa, ARegion *ar, const int mval[2], float co[2])
95 {
96         if (sa) {
97                 switch (sa->spacetype) {
98                         case SPACE_CLIP:
99                         {
100                                 SpaceClip *sc = sa->spacedata.first;
101                                 ED_clip_mouse_pos(sc, ar, mval, co);
102                                 BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
103                                 break;
104                         }
105                         case SPACE_SEQ:
106                         {
107                                 UI_view2d_region_to_view(&ar->v2d, mval[0], mval[1], &co[0], &co[1]);
108                                 break;
109                         }
110                         case SPACE_IMAGE:
111                         {
112                                 float frame_size[2];
113                                 SpaceImage *sima = sa->spacedata.first;
114                                 ED_space_image_get_size_fl(sima, frame_size);
115                                 ED_image_mouse_pos(sima, ar, mval, co);
116                                 BKE_mask_coord_from_frame(co, co, frame_size);
117                                 break;
118                         }
119                         default:
120                                 /* possible other spaces from which mask editing is available */
121                                 BLI_assert(0);
122                                 zero_v2(co);
123                                 break;
124                 }
125         }
126         else {
127                 BLI_assert(0);
128                 zero_v2(co);
129         }
130 }
131
132 /* input:  x/y   - mval space
133  * output: xr/yr - mask point space */
134 void ED_mask_point_pos(ScrArea *sa, ARegion *ar, float x, float y, float *xr, float *yr)
135 {
136         float co[2];
137
138         if (sa) {
139                 switch (sa->spacetype) {
140                         case SPACE_CLIP:
141                         {
142                                 SpaceClip *sc = sa->spacedata.first;
143                                 ED_clip_point_stable_pos(sc, ar, x, y, &co[0], &co[1]);
144                                 BKE_mask_coord_from_movieclip(sc->clip, &sc->user, co, co);
145                                 break;
146                         }
147                         case SPACE_SEQ:
148                                 zero_v2(co); /* MASKTODO */
149                                 break;
150                         case SPACE_IMAGE:
151                         {
152                                 float frame_size[2];
153                                 SpaceImage *sima = sa->spacedata.first;
154                                 ED_space_image_get_size_fl(sima, frame_size);
155                                 ED_image_point_pos(sima, ar, x, y, &co[0], &co[1]);
156                                 BKE_mask_coord_from_frame(co, co, frame_size);
157                                 break;
158                         }
159                         default:
160                                 /* possible other spaces from which mask editing is available */
161                                 BLI_assert(0);
162                                 zero_v2(co);
163                                 break;
164                 }
165         }
166         else {
167                 BLI_assert(0);
168                 zero_v2(co);
169         }
170
171         *xr = co[0];
172         *yr = co[1];
173 }
174
175 void ED_mask_point_pos__reverse(ScrArea *sa, ARegion *ar, float x, float y, float *xr, float *yr)
176 {
177         float co[2];
178
179         if (sa) {
180                 switch (sa->spacetype) {
181                         case SPACE_CLIP:
182                         {
183                                 SpaceClip *sc = sa->spacedata.first;
184                                 co[0] = x;
185                                 co[1] = y;
186                                 BKE_mask_coord_to_movieclip(sc->clip, &sc->user, co, co);
187                                 ED_clip_point_stable_pos__reverse(sc, ar, co, co);
188                                 break;
189                         }
190                         case SPACE_SEQ:
191                                 zero_v2(co); /* MASKTODO */
192                                 break;
193                         case SPACE_IMAGE:
194                         {
195                                 float frame_size[2];
196                                 SpaceImage *sima = sa->spacedata.first;
197                                 ED_space_image_get_size_fl(sima, frame_size);
198
199                                 co[0] = x;
200                                 co[1] = y;
201                                 BKE_mask_coord_to_frame(co, co, frame_size);
202                                 ED_image_point_pos__reverse(sima, ar, co, co);
203                                 break;
204                         }
205                         default:
206                                 /* possible other spaces from which mask editing is available */
207                                 BLI_assert(0);
208                                 zero_v2(co);
209                                 break;
210                 }
211         }
212         else {
213                 BLI_assert(0);
214                 zero_v2(co);
215         }
216
217         *xr = co[0];
218         *yr = co[1];
219 }
220
221 void ED_mask_get_size(ScrArea *sa, int *width, int *height)
222 {
223         if (sa && sa->spacedata.first) {
224                 switch (sa->spacetype) {
225                         case SPACE_CLIP:
226                         {
227                                 SpaceClip *sc = sa->spacedata.first;
228                                 ED_space_clip_get_size(sc, width, height);
229                                 break;
230                         }
231                         case SPACE_SEQ:
232                         {
233 //                              Scene *scene = CTX_data_scene(C);
234 //                              *width = (scene->r.size * scene->r.xsch) / 100;
235 //                              *height = (scene->r.size * scene->r.ysch) / 100;
236                                 break;
237                         }
238                         case SPACE_IMAGE:
239                         {
240                                 SpaceImage *sima = sa->spacedata.first;
241                                 ED_space_image_get_size(sima, width, height);
242                                 break;
243                         }
244                         default:
245                                 /* possible other spaces from which mask editing is available */
246                                 BLI_assert(0);
247                                 *width = 0;
248                                 *height = 0;
249                                 break;
250                 }
251         }
252         else {
253                 BLI_assert(0);
254                 *width = 0;
255                 *height = 0;
256         }
257 }
258
259 void ED_mask_zoom(ScrArea *sa, ARegion *ar, float *zoomx, float *zoomy)
260 {
261         if (sa && sa->spacedata.first) {
262                 switch (sa->spacetype) {
263                         case SPACE_CLIP:
264                         {
265                                 SpaceClip *sc = sa->spacedata.first;
266                                 ED_space_clip_get_zoom(sc, ar, zoomx, zoomy);
267                                 break;
268                         }
269                         case SPACE_SEQ:
270                         {
271                                 *zoomx = *zoomy = 1.0f;
272                                 break;
273                         }
274                         case SPACE_IMAGE:
275                         {
276                                 SpaceImage *sima = sa->spacedata.first;
277                                 ED_space_image_get_zoom(sima, ar, zoomx, zoomy);
278                                 break;
279                         }
280                         default:
281                                 /* possible other spaces from which mask editing is available */
282                                 BLI_assert(0);
283                                 *zoomx = *zoomy = 1.0f;
284                                 break;
285                 }
286         }
287         else {
288                 BLI_assert(0);
289                 *zoomx = *zoomy = 1.0f;
290         }
291 }
292
293 void ED_mask_get_aspect(ScrArea *sa, ARegion *UNUSED(ar), float *aspx, float *aspy)
294 {
295         if (sa && sa->spacedata.first) {
296                 switch (sa->spacetype) {
297                         case SPACE_CLIP:
298                         {
299                                 SpaceClip *sc = sa->spacedata.first;
300                                 ED_space_clip_get_aspect(sc, aspx, aspy);
301                                 break;
302                         }
303                         case SPACE_SEQ:
304                         {
305                                 *aspx = *aspy = 1.0f;  /* MASKTODO - render aspect? */
306                                 break;
307                         }
308                         case SPACE_IMAGE:
309                         {
310                                 SpaceImage *sima = sa->spacedata.first;
311                                 ED_space_image_get_aspect(sima, aspx, aspy);
312                                 break;
313                         }
314                         default:
315                                 /* possible other spaces from which mask editing is available */
316                                 BLI_assert(0);
317                                 *aspx = *aspy = 1.0f;
318                                 break;
319                 }
320         }
321         else {
322                 BLI_assert(0);
323                 *aspx = *aspy = 1.0f;
324         }
325 }
326
327 void ED_mask_pixelspace_factor(ScrArea *sa, ARegion *ar, float *scalex, float *scaley)
328 {
329         if (sa && sa->spacedata.first) {
330                 switch (sa->spacetype) {
331                         case SPACE_CLIP:
332                         {
333                                 SpaceClip *sc = sa->spacedata.first;
334                                 int width, height;
335                                 float zoomx, zoomy, aspx, aspy;
336
337                                 ED_space_clip_get_size(sc, &width, &height);
338                                 ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);
339                                 ED_space_clip_get_aspect(sc, &aspx, &aspy);
340
341                                 *scalex = ((float)width * aspx) * zoomx;
342                                 *scaley = ((float)height * aspy) * zoomy;
343                                 break;
344                         }
345                         case SPACE_SEQ:
346                         {
347                                 *scalex = *scaley = 1.0f;  /* MASKTODO? */
348                                 break;
349                         }
350                         case SPACE_IMAGE:
351                         {
352                                 SpaceImage *sima = sa->spacedata.first;
353                                 int width, height;
354                                 float zoomx, zoomy, aspx, aspy;
355
356                                 ED_space_image_get_size(sima, &width, &height);
357                                 ED_space_image_get_zoom(sima, ar, &zoomx, &zoomy);
358                                 ED_space_image_get_aspect(sima, &aspx, &aspy);
359
360                                 *scalex = ((float)width * aspx) * zoomx;
361                                 *scaley = ((float)height * aspy) * zoomy;
362                                 break;
363                         }
364                         default:
365                                 /* possible other spaces from which mask editing is available */
366                                 BLI_assert(0);
367                                 *scalex = *scaley = 1.0f;
368                                 break;
369                 }
370         }
371         else {
372                 BLI_assert(0);
373                 *scalex = *scaley = 1.0f;
374         }
375 }
376
377 /********************** registration *********************/
378
379 void ED_operatortypes_mask(void)
380 {
381         WM_operatortype_append(MASK_OT_new);
382
383         /* mask layers */
384         WM_operatortype_append(MASK_OT_layer_new);
385         WM_operatortype_append(MASK_OT_layer_remove);
386
387         /* add */
388         WM_operatortype_append(MASK_OT_add_vertex);
389         WM_operatortype_append(MASK_OT_add_feather_vertex);
390
391         /* geometry */
392         WM_operatortype_append(MASK_OT_switch_direction);
393         WM_operatortype_append(MASK_OT_normals_make_consistent);
394         WM_operatortype_append(MASK_OT_delete);
395
396         /* select */
397         WM_operatortype_append(MASK_OT_select);
398         WM_operatortype_append(MASK_OT_select_all);
399         WM_operatortype_append(MASK_OT_select_border);
400         WM_operatortype_append(MASK_OT_select_lasso);
401         WM_operatortype_append(MASK_OT_select_circle);
402         WM_operatortype_append(MASK_OT_select_linked_pick);
403         WM_operatortype_append(MASK_OT_select_linked);
404
405         /* hide/reveal */
406         WM_operatortype_append(MASK_OT_hide_view_clear);
407         WM_operatortype_append(MASK_OT_hide_view_set);
408
409         /* feather */
410         WM_operatortype_append(MASK_OT_feather_weight_clear);
411
412         /* shape */
413         WM_operatortype_append(MASK_OT_slide_point);
414         WM_operatortype_append(MASK_OT_cyclic_toggle);
415         WM_operatortype_append(MASK_OT_handle_type_set);
416
417         /* relationships */
418         WM_operatortype_append(MASK_OT_parent_set);
419         WM_operatortype_append(MASK_OT_parent_clear);
420
421         /* shapekeys */
422         WM_operatortype_append(MASK_OT_shape_key_insert);
423         WM_operatortype_append(MASK_OT_shape_key_clear);
424         WM_operatortype_append(MASK_OT_shape_key_feather_reset);
425         WM_operatortype_append(MASK_OT_shape_key_rekey);
426
427         /* layers */
428         WM_operatortype_append(MASK_OT_layer_move);
429 }
430
431 void ED_keymap_mask(wmKeyConfig *keyconf)
432 {
433         wmKeyMap *keymap;
434         wmKeyMapItem *kmi;
435
436         keymap = WM_keymap_find(keyconf, "Mask Editing", 0, 0);
437         keymap->poll = ED_maskedit_poll;
438
439         WM_keymap_add_item(keymap, "MASK_OT_new", NKEY, KM_PRESS, KM_ALT, 0);
440
441         /* mask mode supports PET now */
442         ED_keymap_proportional_cycle(keyconf, keymap);
443         ED_keymap_proportional_maskmode(keyconf, keymap);
444
445         /* geometry */
446         WM_keymap_add_item(keymap, "MASK_OT_add_vertex_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
447         WM_keymap_add_item(keymap, "MASK_OT_add_feather_vertex_slide", LEFTMOUSE, KM_PRESS, KM_SHIFT, 0);
448         WM_keymap_add_item(keymap, "MASK_OT_delete", XKEY, KM_PRESS, 0, 0);
449         WM_keymap_add_item(keymap, "MASK_OT_delete", DELKEY, KM_PRESS, 0, 0);
450
451         /* selection */
452         kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
453         RNA_boolean_set(kmi->ptr, "extend", FALSE);
454         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
455         RNA_boolean_set(kmi->ptr, "toggle", FALSE);
456         kmi = WM_keymap_add_item(keymap, "MASK_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
457         RNA_boolean_set(kmi->ptr, "extend", FALSE);
458         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
459         RNA_boolean_set(kmi->ptr, "toggle", TRUE);
460
461         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", AKEY, KM_PRESS, 0, 0);
462         RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
463         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
464         RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
465
466         WM_keymap_add_item(keymap, "MASK_OT_select_linked", LKEY, KM_PRESS, KM_CTRL, 0);
467         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, 0, 0);
468         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
469         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_linked_pick", LKEY, KM_PRESS, KM_SHIFT, 0);
470         RNA_boolean_set(kmi->ptr, "deselect", TRUE);
471
472         WM_keymap_add_item(keymap, "MASK_OT_select_border", BKEY, KM_PRESS, 0, 0);
473         WM_keymap_add_item(keymap, "MASK_OT_select_circle", CKEY, KM_PRESS, 0, 0);
474
475         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
476         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
477         kmi = WM_keymap_add_item(keymap, "MASK_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0);
478         RNA_boolean_set(kmi->ptr, "deselect", TRUE);
479
480         /* hide/reveal */
481         WM_keymap_add_item(keymap, "MASK_OT_hide_view_clear", HKEY, KM_PRESS, KM_ALT, 0);
482         kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, 0, 0);
483         RNA_boolean_set(kmi->ptr, "unselected", FALSE);
484
485         kmi = WM_keymap_add_item(keymap, "MASK_OT_hide_view_set", HKEY, KM_PRESS, KM_SHIFT, 0);
486         RNA_boolean_set(kmi->ptr, "unselected", TRUE);
487
488         /* select clip while in maker view,
489          * this matches View3D functionality where you can select an
490          * object while in editmode to allow vertex parenting */
491         kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_CTRL, 0);
492         RNA_boolean_set(kmi->ptr, "extend", FALSE);
493
494         /* shape */
495         WM_keymap_add_item(keymap, "MASK_OT_cyclic_toggle", CKEY, KM_PRESS, KM_ALT, 0);
496         WM_keymap_add_item(keymap, "MASK_OT_slide_point", LEFTMOUSE, KM_PRESS, 0, 0);
497         WM_keymap_add_item(keymap, "MASK_OT_handle_type_set", VKEY, KM_PRESS, 0, 0);
498         WM_keymap_add_item(keymap, "MASK_OT_normals_make_consistent", NKEY, KM_PRESS, KM_CTRL, 0);
499         // WM_keymap_add_item(keymap, "MASK_OT_feather_weight_clear", SKEY, KM_PRESS, KM_ALT, 0);
500         /* ... matches curve editmode */
501
502         /* relationships */
503         WM_keymap_add_item(keymap, "MASK_OT_parent_set", PKEY, KM_PRESS, KM_CTRL, 0);
504         WM_keymap_add_item(keymap, "MASK_OT_parent_clear", PKEY, KM_PRESS, KM_ALT, 0);
505
506         WM_keymap_add_item(keymap, "MASK_OT_shape_key_insert", IKEY, KM_PRESS, 0, 0);
507         WM_keymap_add_item(keymap, "MASK_OT_shape_key_clear", IKEY, KM_PRESS, KM_ALT, 0);
508
509         /* for image editor only */
510         WM_keymap_add_item(keymap, "UV_OT_cursor_set", ACTIONMOUSE, KM_PRESS, 0, 0);
511
512         /* Transform (don't use transform_keymap_for_space() since this maps to different spaces) */
513         WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", GKEY, KM_PRESS, 0, 0);
514         WM_keymap_add_item(keymap, "TRANSFORM_OT_translate", EVT_TWEAK_S, KM_ANY, 0, 0);
515         WM_keymap_add_item(keymap, "TRANSFORM_OT_resize", SKEY, KM_PRESS, 0, 0);
516         WM_keymap_add_item(keymap, "TRANSFORM_OT_rotate", RKEY, KM_PRESS, 0, 0);
517         kmi = WM_keymap_add_item(keymap, "TRANSFORM_OT_transform", SKEY, KM_PRESS, KM_ALT, 0);
518         RNA_enum_set(kmi->ptr, "mode", TFM_MASK_SHRINKFATTEN);
519 }
520
521 void ED_operatormacros_mask(void)
522 {
523         /* XXX: just for sample */
524         wmOperatorType *ot;
525         wmOperatorTypeMacro *otmacro;
526
527         ot = WM_operatortype_append_macro("MASK_OT_add_vertex_slide", "Add Vertex and Slide",
528                                           "Add new vertex and slide it", OPTYPE_UNDO | OPTYPE_REGISTER);
529         ot->description = "Add new vertex and slide it";
530         WM_operatortype_macro_define(ot, "MASK_OT_add_vertex");
531         otmacro = WM_operatortype_macro_define(ot, "TRANSFORM_OT_translate");
532         RNA_boolean_set(otmacro->ptr, "release_confirm", TRUE);
533
534         ot = WM_operatortype_append_macro("MASK_OT_add_feather_vertex_slide", "Add Feather Vertex and Slide",
535                                           "Add new vertex to feather and slide it", OPTYPE_UNDO | OPTYPE_REGISTER);
536         ot->description = "Add new feather vertex and slide it";
537         WM_operatortype_macro_define(ot, "MASK_OT_add_feather_vertex");
538         otmacro = WM_operatortype_macro_define(ot, "MASK_OT_slide_point");
539         RNA_boolean_set(otmacro->ptr, "slide_feather", TRUE);
540 }