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