proportional editing keys now work when editing masks.
[blender.git] / source / blender / editors / space_clip / space_clip.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) 2011 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/space_clip/space_clip.c
29  *  \ingroup spclip
30  */
31
32 #include <string.h>
33 #include <stdio.h>
34
35 #include "DNA_scene_types.h"
36 #include "DNA_mask_types.h"
37 #include "DNA_movieclip_types.h"
38 #include "DNA_view3d_types.h"   /* for pivot point */
39
40 #include "MEM_guardedalloc.h"
41
42 #include "BLI_blenlib.h"
43 #include "BLI_utildefines.h"
44 #include "BLI_math.h"
45
46 #include "BKE_main.h"
47 #include "BKE_context.h"
48 #include "BKE_screen.h"
49 #include "BKE_movieclip.h"
50 #include "BKE_tracking.h"
51
52 #include "IMB_imbuf_types.h"
53
54 #include "ED_mask.h"
55 #include "ED_space_api.h"
56 #include "ED_screen.h"
57 #include "ED_clip.h"
58 #include "ED_transform.h"
59
60 #include "IMB_imbuf.h"
61
62 #include "BIF_gl.h"
63
64 #include "WM_api.h"
65 #include "WM_types.h"
66
67 #include "UI_interface.h"
68 #include "UI_resources.h"
69 #include "UI_view2d.h"
70
71 #include "RNA_access.h"
72
73
74 #include "clip_intern.h"        // own include
75
76 static void init_preview_region(const bContext *C, ARegion *ar)
77 {
78         Scene *scene = CTX_data_scene(C);
79         ScrArea *sa = CTX_wm_area(C);
80         SpaceClip *sc = CTX_wm_space_clip(C);
81
82         ar->regiontype = RGN_TYPE_PREVIEW;
83         ar->alignment = RGN_ALIGN_TOP;
84         ar->flag |= RGN_FLAG_HIDDEN;
85
86         if (sc->view == SC_VIEW_DOPESHEET) {
87                 ar->v2d.tot.xmin = -10.0f;
88                 ar->v2d.tot.ymin = (float)(-sa->winy) / 3.0f;
89                 ar->v2d.tot.xmax = (float)(sa->winx);
90                 ar->v2d.tot.ymax = 0.0f;
91
92                 ar->v2d.cur = ar->v2d.tot;
93
94                 ar->v2d.min[0] = 0.0f;
95                 ar->v2d.min[1] = 0.0f;
96
97                 ar->v2d.max[0] = MAXFRAMEF;
98                 ar->v2d.max[1] = FLT_MAX;
99
100                 ar->v2d.minzoom = 0.01f;
101                 ar->v2d.maxzoom = 50;
102                 ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
103                 ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
104                 ar->v2d.keepzoom = V2D_LOCKZOOM_Y;
105                 ar->v2d.keepofs = V2D_KEEPOFS_Y;
106                 ar->v2d.align = V2D_ALIGN_NO_POS_Y;
107                 ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
108         }
109         else {
110                 ar->v2d.tot.xmin = 0.0f;
111                 ar->v2d.tot.ymin = -10.0f;
112                 ar->v2d.tot.xmax = (float)scene->r.efra;
113                 ar->v2d.tot.ymax = 10.0f;
114
115                 ar->v2d.cur = ar->v2d.tot;
116
117                 ar->v2d.min[0] = FLT_MIN;
118                 ar->v2d.min[1] = FLT_MIN;
119
120                 ar->v2d.max[0] = MAXFRAMEF;
121                 ar->v2d.max[1] = FLT_MAX;
122
123                 ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
124                 ar->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_SCALE_VERTICAL);
125
126                 ar->v2d.minzoom = 0.0f;
127                 ar->v2d.maxzoom = 0.0f;
128                 ar->v2d.keepzoom = 0;
129                 ar->v2d.keepofs = 0;
130                 ar->v2d.align = 0;
131                 ar->v2d.flag = 0;
132
133                 ar->v2d.keeptot = 0;
134         }
135 }
136
137 static void reinit_preview_region(const bContext *C, ARegion *ar)
138 {
139         SpaceClip *sc = CTX_wm_space_clip(C);
140
141         if (sc->view == SC_VIEW_DOPESHEET) {
142                 if ((ar->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL) == 0)
143                         init_preview_region(C, ar);
144         }
145         else {
146                 if (ar->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL)
147                         init_preview_region(C, ar);
148         }
149 }
150
151 static ARegion *ED_clip_has_preview_region(const bContext *C, ScrArea *sa)
152 {
153         ARegion *ar, *arnew;
154
155         ar = BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW);
156         if (ar)
157                 return ar;
158
159         /* add subdiv level; after header */
160         ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
161
162         /* is error! */
163         if (ar == NULL)
164                 return NULL;
165
166         arnew = MEM_callocN(sizeof(ARegion), "clip preview region");
167
168         BLI_insertlinkbefore(&sa->regionbase, ar, arnew);
169         init_preview_region(C, arnew);
170
171         return arnew;
172 }
173
174 static ARegion *ED_clip_has_channels_region(ScrArea *sa)
175 {
176         ARegion *ar, *arnew;
177
178         ar = BKE_area_find_region_type(sa, RGN_TYPE_CHANNELS);
179         if (ar)
180                 return ar;
181
182         /* add subdiv level; after header */
183         ar = BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW);
184
185         /* is error! */
186         if (ar == NULL)
187                 return NULL;
188
189         arnew = MEM_callocN(sizeof(ARegion), "clip channels region");
190
191         BLI_insertlinkbefore(&sa->regionbase, ar, arnew);
192         arnew->regiontype = RGN_TYPE_CHANNELS;
193         arnew->alignment = RGN_ALIGN_LEFT;
194
195         arnew->v2d.scroll = V2D_SCROLL_BOTTOM;
196         arnew->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
197
198         return arnew;
199 }
200
201 static void clip_scopes_tag_refresh(ScrArea *sa)
202 {
203         SpaceClip *sc = (SpaceClip *)sa->spacedata.first;
204         ARegion *ar;
205
206         if (sc->mode != SC_MODE_TRACKING)
207                 return;
208
209         /* only while proeprties are visible */
210         for (ar = sa->regionbase.first; ar; ar = ar->next) {
211                 if (ar->regiontype == RGN_TYPE_UI && ar->flag & RGN_FLAG_HIDDEN)
212                         return;
213         }
214
215         sc->scopes.ok = FALSE;
216 }
217
218 static void clip_stabilization_tag_refresh(ScrArea *sa)
219 {
220         SpaceClip *sc = (SpaceClip *) sa->spacedata.first;
221         MovieClip *clip = ED_space_clip(sc);
222
223         if (clip) {
224                 MovieTrackingStabilization *stab = &clip->tracking.stabilization;
225
226                 stab->ok = FALSE;
227         }
228 }
229
230 /* ******************** default callbacks for clip space ***************** */
231
232 static SpaceLink *clip_new(const bContext *C)
233 {
234         ARegion *ar;
235         SpaceClip *sc;
236
237         sc = MEM_callocN(sizeof(SpaceClip), "initclip");
238         sc->spacetype = SPACE_CLIP;
239         sc->flag = SC_SHOW_MARKER_PATTERN | SC_SHOW_TRACK_PATH | SC_MANUAL_CALIBRATION |
240                    SC_SHOW_GRAPH_TRACKS | SC_SHOW_GRAPH_FRAMES;
241         sc->zoom = 1.0f;
242         sc->path_length = 20;
243         sc->scopes.track_preview_height = 120;
244         sc->around = V3D_LOCAL;
245
246         /* header */
247         ar = MEM_callocN(sizeof(ARegion), "header for clip");
248
249         BLI_addtail(&sc->regionbase, ar);
250         ar->regiontype = RGN_TYPE_HEADER;
251         ar->alignment = RGN_ALIGN_BOTTOM;
252
253         /* tools view */
254         ar = MEM_callocN(sizeof(ARegion), "tools for clip");
255
256         BLI_addtail(&sc->regionbase, ar);
257         ar->regiontype = RGN_TYPE_TOOLS;
258         ar->alignment = RGN_ALIGN_LEFT;
259
260         /* tool properties */
261         ar = MEM_callocN(sizeof(ARegion), "tool properties for clip");
262
263         BLI_addtail(&sc->regionbase, ar);
264         ar->regiontype = RGN_TYPE_TOOL_PROPS;
265         ar->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
266
267         /* properties view */
268         ar = MEM_callocN(sizeof(ARegion), "properties for clip");
269
270         BLI_addtail(&sc->regionbase, ar);
271         ar->regiontype = RGN_TYPE_UI;
272         ar->alignment = RGN_ALIGN_RIGHT;
273
274         /* channels view */
275         ar = MEM_callocN(sizeof(ARegion), "channels for clip");
276
277         BLI_addtail(&sc->regionbase, ar);
278         ar->regiontype = RGN_TYPE_CHANNELS;
279         ar->alignment = RGN_ALIGN_LEFT;
280
281         ar->v2d.scroll = V2D_SCROLL_BOTTOM;
282         ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
283
284         /* preview view */
285         ar = MEM_callocN(sizeof(ARegion), "preview for clip");
286
287         BLI_addtail(&sc->regionbase, ar);
288         init_preview_region(C, ar);
289
290         /* main area */
291         ar = MEM_callocN(sizeof(ARegion), "main area for clip");
292
293         BLI_addtail(&sc->regionbase, ar);
294         ar->regiontype = RGN_TYPE_WINDOW;
295
296         return (SpaceLink *) sc;
297 }
298
299 /* not spacelink itself */
300 static void clip_free(SpaceLink *sl)
301 {
302         SpaceClip *sc = (SpaceClip*) sl;
303
304         sc->clip = NULL;
305
306         if (sc->scopes.track_preview)
307                 IMB_freeImBuf(sc->scopes.track_preview);
308
309         ED_space_clip_free_texture_buffer(sc);
310 }
311
312 /* spacetype; init callback */
313 static void clip_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
314 {
315         ListBase *lb = WM_dropboxmap_find("Clip", SPACE_CLIP, 0);
316
317         /* add drop boxes */
318         WM_event_add_dropbox_handler(&sa->handlers, lb);
319 }
320
321 static SpaceLink *clip_duplicate(SpaceLink *sl)
322 {
323         SpaceClip *scn = MEM_dupallocN(sl);
324
325         /* clear or remove stuff from old */
326         scn->scopes.track_preview = NULL;
327         scn->scopes.ok = FALSE;
328         scn->draw_context = NULL;
329
330         return (SpaceLink *)scn;
331 }
332
333 static void clip_listener(ScrArea *sa, wmNotifier *wmn)
334 {
335         /* context changes */
336         switch (wmn->category) {
337                 case NC_SCENE:
338                         switch (wmn->data) {
339                                 case ND_FRAME:
340                                         clip_scopes_tag_refresh(sa);
341                                         /* no break! */
342
343                                 case ND_FRAME_RANGE:
344                                         ED_area_tag_redraw(sa);
345                                         break;
346                         }
347                         break;
348                 case NC_MOVIECLIP:
349                         switch (wmn->data) {
350                                 case ND_DISPLAY:
351                                 case ND_SELECT:
352                                         clip_scopes_tag_refresh(sa);
353                                         ED_area_tag_redraw(sa);
354                                         break;
355                         }
356                         switch (wmn->action) {
357                                 case NA_REMOVED:
358                                 case NA_EDITED:
359                                 case NA_EVALUATED:
360                                         clip_stabilization_tag_refresh(sa);
361                                         /* no break! */
362
363                                 case NA_SELECTED:
364                                         clip_scopes_tag_refresh(sa);
365                                         ED_area_tag_redraw(sa);
366                                         break;
367                         }
368                         break;
369                 case NC_MASK:
370                         switch(wmn->data) {
371                                 case ND_SELECT:
372                                 case ND_DATA:
373                                 case ND_DRAW:
374                                         ED_area_tag_redraw(sa);
375                                         break;
376                         }
377                         switch(wmn->action) {
378                                 case NA_SELECTED:
379                                         clip_scopes_tag_refresh(sa);
380                                         ED_area_tag_redraw(sa);
381                                         break;
382                                 case NA_EDITED:
383                                         ED_area_tag_redraw(sa);
384                                         break;
385                         }
386                         break;
387                 case NC_GEOM:
388                         switch (wmn->data) {
389                                 case ND_SELECT:
390                                         clip_scopes_tag_refresh(sa);
391                                         ED_area_tag_redraw(sa);
392                                         break;
393                         }
394                         break;
395                  case NC_SCREEN:
396                          switch (wmn->data) {
397                                 case ND_ANIMPLAY:
398                                 case ND_GPENCIL:
399                                         ED_area_tag_redraw(sa);
400                                         break;
401                         }
402                         break;
403                 case NC_SPACE:
404                         if (wmn->data == ND_SPACE_CLIP) {
405                                 clip_scopes_tag_refresh(sa);
406                                 clip_stabilization_tag_refresh(sa);
407                                 ED_area_tag_redraw(sa);
408                         }
409                         break;
410         }
411 }
412
413 static void clip_operatortypes(void)
414 {
415         /* ** clip_ops.c ** */
416         WM_operatortype_append(CLIP_OT_open);
417         WM_operatortype_append(CLIP_OT_reload);
418         WM_operatortype_append(CLIP_OT_view_pan);
419         WM_operatortype_append(CLIP_OT_view_zoom);
420         WM_operatortype_append(CLIP_OT_view_zoom_in);
421         WM_operatortype_append(CLIP_OT_view_zoom_out);
422         WM_operatortype_append(CLIP_OT_view_zoom_ratio);
423         WM_operatortype_append(CLIP_OT_view_all);
424         WM_operatortype_append(CLIP_OT_view_selected);
425         WM_operatortype_append(CLIP_OT_change_frame);
426         WM_operatortype_append(CLIP_OT_rebuild_proxy);
427         WM_operatortype_append(CLIP_OT_mode_set);
428
429         /* ** clip_toolbar.c ** */
430         WM_operatortype_append(CLIP_OT_tools);
431         WM_operatortype_append(CLIP_OT_properties);
432
433         /* ** tracking_ops.c ** */
434
435         /* navigation */
436         WM_operatortype_append(CLIP_OT_frame_jump);
437
438         /* foorage */
439         WM_operatortype_append(CLIP_OT_set_center_principal);
440
441         /* selection */
442         WM_operatortype_append(CLIP_OT_select);
443         WM_operatortype_append(CLIP_OT_select_all);
444         WM_operatortype_append(CLIP_OT_select_border);
445         WM_operatortype_append(CLIP_OT_select_lasso);
446         WM_operatortype_append(CLIP_OT_select_circle);
447         WM_operatortype_append(CLIP_OT_select_grouped);
448
449         /* markers */
450         WM_operatortype_append(CLIP_OT_add_marker);
451         WM_operatortype_append(CLIP_OT_slide_marker);
452         WM_operatortype_append(CLIP_OT_delete_track);
453         WM_operatortype_append(CLIP_OT_delete_marker);
454
455         /* track */
456         WM_operatortype_append(CLIP_OT_track_markers);
457
458         /* solving */
459         WM_operatortype_append(CLIP_OT_solve_camera);
460         WM_operatortype_append(CLIP_OT_clear_solution);
461
462         WM_operatortype_append(CLIP_OT_disable_markers);
463         WM_operatortype_append(CLIP_OT_hide_tracks);
464         WM_operatortype_append(CLIP_OT_hide_tracks_clear);
465         WM_operatortype_append(CLIP_OT_lock_tracks);
466
467         /* orientation */
468         WM_operatortype_append(CLIP_OT_set_origin);
469         WM_operatortype_append(CLIP_OT_set_plane);
470         WM_operatortype_append(CLIP_OT_set_axis);
471         WM_operatortype_append(CLIP_OT_set_scale);
472         WM_operatortype_append(CLIP_OT_set_solution_scale);
473
474         /* detect */
475         WM_operatortype_append(CLIP_OT_detect_features);
476
477         /* stabilization */
478         WM_operatortype_append(CLIP_OT_stabilize_2d_add);
479         WM_operatortype_append(CLIP_OT_stabilize_2d_remove);
480         WM_operatortype_append(CLIP_OT_stabilize_2d_select);
481         WM_operatortype_append(CLIP_OT_stabilize_2d_set_rotation);
482
483         /* clean-up */
484         WM_operatortype_append(CLIP_OT_clear_track_path);
485         WM_operatortype_append(CLIP_OT_join_tracks);
486         WM_operatortype_append(CLIP_OT_track_copy_color);
487
488         WM_operatortype_append(CLIP_OT_clean_tracks);
489
490         /* object tracking */
491         WM_operatortype_append(CLIP_OT_tracking_object_new);
492         WM_operatortype_append(CLIP_OT_tracking_object_remove);
493
494         /* clipboard */
495         WM_operatortype_append(CLIP_OT_copy_tracks);
496         WM_operatortype_append(CLIP_OT_paste_tracks);
497
498         /* ** clip_graph_ops.c  ** */
499
500         /* graph editing */
501
502         /* selection */
503         WM_operatortype_append(CLIP_OT_graph_select);
504         WM_operatortype_append(CLIP_OT_graph_select_border);
505         WM_operatortype_append(CLIP_OT_graph_select_all_markers);
506
507         WM_operatortype_append(CLIP_OT_graph_delete_curve);
508         WM_operatortype_append(CLIP_OT_graph_delete_knot);
509         WM_operatortype_append(CLIP_OT_graph_view_all);
510         WM_operatortype_append(CLIP_OT_graph_center_current_frame);
511
512         WM_operatortype_append(CLIP_OT_graph_disable_markers);
513
514         /* ** clip_dopesheet_ops.c  ** */
515
516         WM_operatortype_append(CLIP_OT_dopesheet_select_channel);
517 }
518
519 static void clip_keymap(struct wmKeyConfig *keyconf)
520 {
521         wmKeyMap *keymap;
522         wmKeyMapItem *kmi;
523
524         /* ******** Global hotkeys avalaible for all regions ******** */
525
526         keymap = WM_keymap_find(keyconf, "Clip", SPACE_CLIP, 0);
527
528         WM_keymap_add_item(keymap, "CLIP_OT_open", OKEY, KM_PRESS, KM_ALT, 0);
529
530         WM_keymap_add_item(keymap, "CLIP_OT_tools", TKEY, KM_PRESS, 0, 0);
531         WM_keymap_add_item(keymap, "CLIP_OT_properties", NKEY, KM_PRESS, 0, 0);
532
533         /* 2d tracking */
534         kmi = WM_keymap_add_item(keymap, "CLIP_OT_track_markers", LEFTARROWKEY, KM_PRESS, KM_ALT, 0);
535         RNA_boolean_set(kmi->ptr, "backwards", TRUE);
536         RNA_boolean_set(kmi->ptr, "sequence", FALSE);
537         kmi = WM_keymap_add_item(keymap, "CLIP_OT_track_markers", RIGHTARROWKEY, KM_PRESS, KM_ALT, 0);
538         RNA_boolean_set(kmi->ptr, "backwards", FALSE);
539         RNA_boolean_set(kmi->ptr, "sequence", FALSE);
540         kmi = WM_keymap_add_item(keymap, "CLIP_OT_track_markers", TKEY, KM_PRESS, KM_CTRL, 0);
541         RNA_boolean_set(kmi->ptr, "backwards", FALSE);
542         RNA_boolean_set(kmi->ptr, "sequence", TRUE);
543         kmi = WM_keymap_add_item(keymap, "CLIP_OT_track_markers", TKEY, KM_PRESS, KM_SHIFT | KM_CTRL, 0);
544         RNA_boolean_set(kmi->ptr, "backwards", TRUE);
545         RNA_boolean_set(kmi->ptr, "sequence", TRUE);
546
547         /* mode */
548         kmi = WM_keymap_add_item(keymap, "CLIP_OT_mode_set", TABKEY, KM_PRESS, 0, 0);
549         RNA_enum_set(kmi->ptr, "mode", SC_MODE_RECONSTRUCTION);
550         RNA_boolean_set(kmi->ptr, "toggle", TRUE);
551
552         kmi = WM_keymap_add_item(keymap, "CLIP_OT_mode_set", TABKEY, KM_PRESS, KM_CTRL, 0);
553         RNA_enum_set(kmi->ptr, "mode", SC_MODE_DISTORTION);
554         RNA_boolean_set(kmi->ptr, "toggle", TRUE);
555
556         WM_keymap_add_item(keymap, "CLIP_OT_solve_camera", SKEY, KM_PRESS, KM_SHIFT, 0);
557
558         /* ******** Hotkeys avalaible for main region only ******** */
559
560         keymap = WM_keymap_find(keyconf, "Clip Editor", SPACE_CLIP, 0);
561 //      keymap->poll = ED_space_clip_tracking_poll;
562         /* ** View/navigation ** */
563
564         WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, 0, 0);
565         WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MIDDLEMOUSE, KM_PRESS, KM_SHIFT, 0);
566         WM_keymap_add_item(keymap, "CLIP_OT_view_pan", MOUSEPAN, 0, 0, 0);
567
568         WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MIDDLEMOUSE, KM_PRESS, KM_CTRL, 0);
569         WM_keymap_add_item(keymap, "CLIP_OT_view_zoom", MOUSEZOOM, 0, 0, 0);
570         WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", WHEELINMOUSE, KM_PRESS, 0, 0);
571         WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", WHEELOUTMOUSE, KM_PRESS, 0, 0);
572         WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_in", PADPLUSKEY, KM_PRESS, 0, 0);
573         WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_out", PADMINUS, KM_PRESS, 0, 0);
574
575         RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD8, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 8.0f);
576         RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 4.0f);
577         RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, KM_SHIFT, 0)->ptr, "ratio", 2.0f);
578         RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD1, KM_PRESS, 0, 0)->ptr, "ratio", 1.0f);
579         RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD2, KM_PRESS, 0, 0)->ptr, "ratio", 0.5f);
580         RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD4, KM_PRESS, 0, 0)->ptr, "ratio", 0.25f);
581         RNA_float_set(WM_keymap_add_item(keymap, "CLIP_OT_view_zoom_ratio", PAD8, KM_PRESS, 0, 0)->ptr, "ratio", 0.125f);
582
583         WM_keymap_add_item(keymap, "CLIP_OT_view_all", HOMEKEY, KM_PRESS, 0, 0);
584
585         kmi = WM_keymap_add_item(keymap, "CLIP_OT_view_all", FKEY, KM_PRESS, 0, 0);
586         RNA_boolean_set(kmi->ptr, "fit_view", TRUE);
587
588         WM_keymap_add_item(keymap, "CLIP_OT_view_selected", PADPERIOD, KM_PRESS, 0, 0);
589
590         /* jump to special frame */
591         kmi = WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
592         RNA_enum_set(kmi->ptr, "position", 0);
593
594         kmi = WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_CTRL | KM_SHIFT, 0);
595         RNA_enum_set(kmi->ptr, "position", 1);
596
597         kmi = WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", LEFTARROWKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0);
598         RNA_enum_set(kmi->ptr, "position", 2);
599
600         kmi = WM_keymap_add_item(keymap, "CLIP_OT_frame_jump", RIGHTARROWKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0);
601         RNA_enum_set(kmi->ptr, "position", 3);
602
603         /* "timeline" */
604         WM_keymap_add_item(keymap, "CLIP_OT_change_frame", LEFTMOUSE, KM_PRESS, 0, 0);
605
606         /* selection */
607         kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, 0, 0);
608         RNA_boolean_set(kmi->ptr, "extend", FALSE);
609         kmi = WM_keymap_add_item(keymap, "CLIP_OT_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
610         RNA_boolean_set(kmi->ptr, "extend", TRUE);
611         kmi = WM_keymap_add_item(keymap, "CLIP_OT_select_all", AKEY, KM_PRESS, 0, 0);
612         RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
613         kmi = WM_keymap_add_item(keymap, "CLIP_OT_select_all", IKEY, KM_PRESS, KM_CTRL, 0);
614         RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
615         WM_keymap_add_item(keymap, "CLIP_OT_select_border", BKEY, KM_PRESS, 0, 0);
616         WM_keymap_add_item(keymap, "CLIP_OT_select_circle", CKEY, KM_PRESS, 0, 0);
617         WM_keymap_add_menu(keymap, "CLIP_MT_select_grouped", GKEY, KM_PRESS, KM_SHIFT, 0);
618
619         kmi = WM_keymap_add_item(keymap, "CLIP_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_ALT, 0);
620         RNA_boolean_set(kmi->ptr, "deselect", FALSE);
621         kmi = WM_keymap_add_item(keymap, "CLIP_OT_select_lasso", EVT_TWEAK_A, KM_ANY, KM_CTRL | KM_SHIFT | KM_ALT, 0);
622         RNA_boolean_set(kmi->ptr, "deselect", TRUE);
623
624         /* marker */
625         WM_keymap_add_item(keymap, "CLIP_OT_add_marker_slide", LEFTMOUSE, KM_PRESS, KM_CTRL, 0);
626
627         WM_keymap_add_item(keymap, "CLIP_OT_delete_marker", DELKEY, KM_PRESS, KM_SHIFT, 0);
628         WM_keymap_add_item(keymap, "CLIP_OT_delete_marker", XKEY, KM_PRESS, KM_SHIFT, 0);
629
630         WM_keymap_add_item(keymap, "CLIP_OT_slide_marker", LEFTMOUSE, KM_PRESS, 0, 0);
631
632         kmi = WM_keymap_add_item(keymap, "CLIP_OT_disable_markers", DKEY, KM_PRESS, KM_SHIFT, 0);
633         RNA_enum_set(kmi->ptr, "action", 2);    /* toggle */
634
635         /* tracks */
636         WM_keymap_add_item(keymap, "CLIP_OT_delete_track", DELKEY, KM_PRESS, 0, 0);
637         WM_keymap_add_item(keymap, "CLIP_OT_delete_track", XKEY, KM_PRESS, 0, 0);
638
639         kmi = WM_keymap_add_item(keymap, "CLIP_OT_lock_tracks", LKEY, KM_PRESS, KM_CTRL, 0);
640         RNA_enum_set(kmi->ptr, "action", 0);    /* lock */
641
642         kmi = WM_keymap_add_item(keymap, "CLIP_OT_lock_tracks", LKEY, KM_PRESS, KM_ALT, 0);
643         RNA_enum_set(kmi->ptr, "action", 1);    /* unlock */
644
645         kmi = WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, 0, 0);
646         RNA_boolean_set(kmi->ptr, "unselected", FALSE);
647
648         kmi = WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks", HKEY, KM_PRESS, KM_SHIFT, 0);
649         RNA_boolean_set(kmi->ptr, "unselected", TRUE);
650
651         WM_keymap_add_item(keymap, "CLIP_OT_hide_tracks_clear", HKEY, KM_PRESS, KM_ALT, 0);
652
653         /* clean-up */
654         WM_keymap_add_item(keymap, "CLIP_OT_join_tracks", JKEY, KM_PRESS, KM_CTRL, 0);
655
656         /* menus */
657         WM_keymap_add_menu(keymap, "CLIP_MT_tracking_specials", WKEY, KM_PRESS, 0, 0);
658
659         /* display */
660         kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", LKEY, KM_PRESS, 0, 0);
661         RNA_string_set(kmi->ptr, "data_path", "space_data.lock_selection");
662
663         kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", DKEY, KM_PRESS, KM_ALT, 0);
664         RNA_string_set(kmi->ptr, "data_path", "space_data.show_disabled");
665
666         kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", SKEY, KM_PRESS, KM_ALT, 0);
667         RNA_string_set(kmi->ptr, "data_path", "space_data.show_marker_search");
668
669         kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", MKEY, KM_PRESS, 0, 0);
670         RNA_string_set(kmi->ptr, "data_path", "space_data.use_mute_footage");
671
672         transform_keymap_for_space(keyconf, keymap, SPACE_CLIP);
673
674         /* clean-up */
675         kmi = WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT, 0);
676         RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_REMAINED);
677         RNA_boolean_set(kmi->ptr, "clear_active", FALSE);
678         kmi = WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_SHIFT, 0);
679         RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_UPTO);
680         RNA_boolean_set(kmi->ptr, "clear_active", FALSE);
681         kmi = WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0);
682         RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_ALL);
683         RNA_boolean_set(kmi->ptr, "clear_active", FALSE);
684
685         /* ******** Hotkeys avalaible for preview region only ******** */
686
687         keymap = WM_keymap_find(keyconf, "Clip Graph Editor", SPACE_CLIP, 0);
688
689         /* "timeline" */
690         WM_keymap_add_item(keymap, "CLIP_OT_change_frame", ACTIONMOUSE, KM_PRESS, 0, 0);
691
692         /* selection */
693         kmi = WM_keymap_add_item(keymap, "CLIP_OT_graph_select", SELECTMOUSE, KM_PRESS, 0, 0);
694         RNA_boolean_set(kmi->ptr, "extend", FALSE);
695         kmi = WM_keymap_add_item(keymap, "CLIP_OT_graph_select", SELECTMOUSE, KM_PRESS, KM_SHIFT, 0);
696         RNA_boolean_set(kmi->ptr, "extend", TRUE);
697
698         kmi = WM_keymap_add_item(keymap, "CLIP_OT_graph_select_all_markers", AKEY, KM_PRESS, 0, 0);
699         RNA_enum_set(kmi->ptr, "action", SEL_TOGGLE);
700         kmi = WM_keymap_add_item(keymap, "CLIP_OT_graph_select_all_markers", IKEY, KM_PRESS, KM_CTRL, 0);
701         RNA_enum_set(kmi->ptr, "action", SEL_INVERT);
702
703         WM_keymap_add_item(keymap, "CLIP_OT_graph_select_border", BKEY, KM_PRESS, 0, 0);
704
705         /* delete */
706         WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_curve", DELKEY, KM_PRESS, 0, 0);
707         WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_curve", XKEY, KM_PRESS, 0, 0);
708
709         WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_knot", DELKEY, KM_PRESS, KM_SHIFT, 0);
710         WM_keymap_add_item(keymap, "CLIP_OT_graph_delete_knot", XKEY, KM_PRESS, KM_SHIFT, 0);
711
712         /* view */
713         WM_keymap_add_item(keymap, "CLIP_OT_graph_view_all", HOMEKEY, KM_PRESS, 0, 0);
714         WM_keymap_add_item(keymap, "CLIP_OT_graph_center_current_frame", PADPERIOD, KM_PRESS, 0, 0);
715
716         kmi = WM_keymap_add_item(keymap, "WM_OT_context_toggle", LKEY, KM_PRESS, 0, 0);
717         RNA_string_set(kmi->ptr, "data_path", "space_data.lock_time_cursor");
718
719         /* clean-up */
720         kmi = WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT, 0);
721         RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_REMAINED);
722         RNA_boolean_set(kmi->ptr, "clear_active", TRUE);
723         kmi = WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_SHIFT, 0);
724         RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_UPTO);
725         RNA_boolean_set(kmi->ptr, "clear_active", TRUE);
726         kmi = WM_keymap_add_item(keymap, "CLIP_OT_clear_track_path", TKEY, KM_PRESS, KM_ALT | KM_SHIFT, 0);
727         RNA_enum_set(kmi->ptr, "action", TRACK_CLEAR_ALL);
728         RNA_boolean_set(kmi->ptr, "clear_active", TRUE);
729
730         /* tracks */
731         kmi = WM_keymap_add_item(keymap, "CLIP_OT_graph_disable_markers", DKEY, KM_PRESS, KM_SHIFT, 0);
732         RNA_enum_set(kmi->ptr, "action", 2);    /* toggle */
733
734         transform_keymap_for_space(keyconf, keymap, SPACE_CLIP);
735
736         /* ******** Hotkeys avalaible for channels region only ******** */
737
738         keymap = WM_keymap_find(keyconf, "Clip Dopesheet Editor", SPACE_CLIP, 0);
739
740         kmi = WM_keymap_add_item(keymap, "CLIP_OT_dopesheet_select_channel", ACTIONMOUSE, KM_PRESS, 0, 0);
741         RNA_boolean_set(kmi->ptr, "extend", TRUE);      /* toggle */
742 }
743
744 const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL};
745
746 static int clip_context(const bContext *C, const char *member, bContextDataResult *result)
747 {
748         SpaceClip *sc = CTX_wm_space_clip(C);
749
750         if (CTX_data_dir(member)) {
751                 CTX_data_dir_set(result, clip_context_dir);
752
753                 return TRUE;
754         }
755         else if (CTX_data_equals(member, "edit_movieclip")) {
756                 if (sc->clip)
757                         CTX_data_id_pointer_set(result, &sc->clip->id);
758                 return TRUE;
759         }
760         else if (CTX_data_equals(member, "edit_mask")) {
761                 if (sc->mask)
762                         CTX_data_id_pointer_set(result, &sc->mask->id);
763                 return TRUE;
764         }
765
766         return FALSE;
767 }
768
769 /* dropboxes */
770 static int clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
771 {
772         if (drag->type == WM_DRAG_PATH)
773                 if (ELEM3(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_BLANK)) /* rule might not work? */
774                         return TRUE;
775
776         return FALSE;
777 }
778
779 static void clip_drop_copy(wmDrag *drag, wmDropBox *drop)
780 {
781         /* copy drag path to properties */
782         RNA_string_set(drop->ptr, "filepath", drag->path);
783 }
784
785 /* area+region dropbox definition */
786 static void clip_dropboxes(void)
787 {
788         ListBase *lb = WM_dropboxmap_find("Clip", SPACE_CLIP, 0);
789
790         WM_dropbox_add(lb, "CLIP_OT_open", clip_drop_poll, clip_drop_copy);
791 }
792
793 static void clip_refresh(const bContext *C, ScrArea *sa)
794 {
795         wmWindowManager *wm = CTX_wm_manager(C);
796         wmWindow *window = CTX_wm_window(C);
797         Scene *scene = CTX_data_scene(C);
798         SpaceClip *sc = (SpaceClip *)sa->spacedata.first;
799         ARegion *ar_main = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
800         ARegion *ar_tools = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
801         ARegion *ar_tool_props = BKE_area_find_region_type(sa, RGN_TYPE_TOOL_PROPS);
802         ARegion *ar_preview = ED_clip_has_preview_region(C, sa);
803         ARegion *ar_properties = ED_clip_has_properties_region(sa);
804         ARegion *ar_channels = ED_clip_has_channels_region(sa);
805         int main_visible = FALSE, preview_visible = FALSE, tools_visible = FALSE;
806         int tool_props_visible = FALSE, properties_visible = FALSE, channels_visible = FALSE;
807         int view_changed = FALSE;
808
809         switch (sc->view) {
810                 case SC_VIEW_CLIP:
811                         main_visible = TRUE;
812                         preview_visible = FALSE;
813                         tools_visible = TRUE;
814                         tool_props_visible = TRUE;
815                         properties_visible = TRUE;
816                         channels_visible = FALSE;
817                         break;
818                 case SC_VIEW_GRAPH:
819                         main_visible = FALSE;
820                         preview_visible = TRUE;
821                         tools_visible = FALSE;
822                         tool_props_visible = FALSE;
823                         properties_visible = FALSE;
824                         channels_visible = FALSE;
825
826                         reinit_preview_region(C, ar_preview);
827                         break;
828                 case SC_VIEW_DOPESHEET:
829                         main_visible = FALSE;
830                         preview_visible = TRUE;
831                         tools_visible = FALSE;
832                         tool_props_visible = FALSE;
833                         properties_visible = FALSE;
834                         channels_visible = TRUE;
835
836                         reinit_preview_region(C, ar_preview);
837                         break;
838         }
839
840         if (main_visible) {
841                 if (ar_main && (ar_main->flag & RGN_FLAG_HIDDEN)) {
842                         ar_main->flag &= ~RGN_FLAG_HIDDEN;
843                         ar_main->v2d.flag &= ~V2D_IS_INITIALISED;
844                         view_changed = TRUE;
845                 }
846
847                 if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) {
848                         ar_main->alignment = RGN_ALIGN_NONE;
849                         view_changed = TRUE;
850                 }
851         }
852         else {
853                 if (ar_main && !(ar_main->flag & RGN_FLAG_HIDDEN)) {
854                         ar_main->flag |= RGN_FLAG_HIDDEN;
855                         ar_main->v2d.flag &= ~V2D_IS_INITIALISED;
856                         WM_event_remove_handlers((bContext *)C, &ar_main->handlers);
857                         view_changed = TRUE;
858                 }
859                 if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) {
860                         ar_main->alignment = RGN_ALIGN_NONE;
861                         view_changed = TRUE;
862                 }
863         }
864
865         if (properties_visible) {
866                 if (ar_properties && (ar_properties->flag & RGN_FLAG_HIDDEN)) {
867                         ar_properties->flag &= ~RGN_FLAG_HIDDEN;
868                         ar_properties->v2d.flag &= ~V2D_IS_INITIALISED;
869                         view_changed = TRUE;
870                 }
871                 if (ar_properties && ar_properties->alignment != RGN_ALIGN_RIGHT) {
872                         ar_properties->alignment = RGN_ALIGN_RIGHT;
873                         view_changed = TRUE;
874                 }
875         }
876         else {
877                 if (ar_properties && !(ar_properties->flag & RGN_FLAG_HIDDEN)) {
878                         ar_properties->flag |= RGN_FLAG_HIDDEN;
879                         ar_properties->v2d.flag &= ~V2D_IS_INITIALISED;
880                         WM_event_remove_handlers((bContext *)C, &ar_properties->handlers);
881                         view_changed = TRUE;
882                 }
883                 if (ar_properties && ar_properties->alignment != RGN_ALIGN_NONE) {
884                         ar_properties->alignment = RGN_ALIGN_NONE;
885                         view_changed = TRUE;
886                 }
887         }
888
889         if (tools_visible) {
890                 if (ar_tools && (ar_tools->flag & RGN_FLAG_HIDDEN)) {
891                         ar_tools->flag &= ~RGN_FLAG_HIDDEN;
892                         ar_tools->v2d.flag &= ~V2D_IS_INITIALISED;
893                         view_changed = TRUE;
894                 }
895                 if (ar_tools && ar_tools->alignment != RGN_ALIGN_LEFT) {
896                         ar_tools->alignment = RGN_ALIGN_LEFT;
897                         view_changed = TRUE;
898                 }
899         }
900         else {
901                 if (ar_tools && !(ar_tools->flag & RGN_FLAG_HIDDEN)) {
902                         ar_tools->flag |= RGN_FLAG_HIDDEN;
903                         ar_tools->v2d.flag &= ~V2D_IS_INITIALISED;
904                         WM_event_remove_handlers((bContext *)C, &ar_tools->handlers);
905                         view_changed = TRUE;
906                 }
907                 if (ar_tools && ar_tools->alignment != RGN_ALIGN_NONE) {
908                         ar_tools->alignment = RGN_ALIGN_NONE;
909                         view_changed = TRUE;
910                 }
911         }
912
913         if (tool_props_visible) {
914                 if (ar_tool_props && (ar_tool_props->flag & RGN_FLAG_HIDDEN)) {
915                         ar_tool_props->flag &= ~RGN_FLAG_HIDDEN;
916                         ar_tool_props->v2d.flag &= ~V2D_IS_INITIALISED;
917                         view_changed = TRUE;
918                 }
919                 if (ar_tool_props && (ar_tool_props->alignment != (RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV))) {
920                         ar_tool_props->alignment = RGN_ALIGN_BOTTOM | RGN_SPLIT_PREV;
921                         view_changed = TRUE;
922                 }
923         }
924         else {
925                 if (ar_tool_props && !(ar_tool_props->flag & RGN_FLAG_HIDDEN)) {
926                         ar_tool_props->flag |= RGN_FLAG_HIDDEN;
927                         ar_tool_props->v2d.flag &= ~V2D_IS_INITIALISED;
928                         WM_event_remove_handlers((bContext *)C, &ar_tool_props->handlers);
929                         view_changed = TRUE;
930                 }
931                 if (ar_tool_props && ar_tool_props->alignment != RGN_ALIGN_NONE) {
932                         ar_tool_props->alignment = RGN_ALIGN_NONE;
933                         view_changed = TRUE;
934                 }
935         }
936
937         if (preview_visible) {
938                 if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) {
939                         ar_preview->flag &= ~RGN_FLAG_HIDDEN;
940                         ar_preview->v2d.flag &= ~V2D_IS_INITIALISED;
941                         ar_preview->v2d.cur = ar_preview->v2d.tot;
942                         view_changed = TRUE;
943                 }
944                 if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) {
945                         ar_preview->alignment = RGN_ALIGN_NONE;
946                         view_changed = TRUE;
947                 }
948         }
949         else {
950                 if (ar_preview && !(ar_preview->flag & RGN_FLAG_HIDDEN)) {
951                         ar_preview->flag |= RGN_FLAG_HIDDEN;
952                         ar_preview->v2d.flag &= ~V2D_IS_INITIALISED;
953                         WM_event_remove_handlers((bContext *)C, &ar_preview->handlers);
954                         view_changed = TRUE;
955                 }
956                 if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) {
957                         ar_preview->alignment = RGN_ALIGN_NONE;
958                         view_changed = TRUE;
959                 }
960         }
961
962         if (channels_visible) {
963                 if (ar_channels && (ar_channels->flag & RGN_FLAG_HIDDEN)) {
964                         ar_channels->flag &= ~RGN_FLAG_HIDDEN;
965                         ar_channels->v2d.flag &= ~V2D_IS_INITIALISED;
966                         view_changed = TRUE;
967                 }
968                 if (ar_channels && ar_channels->alignment != RGN_ALIGN_LEFT) {
969                         ar_channels->alignment = RGN_ALIGN_LEFT;
970                         view_changed = TRUE;
971                 }
972         }
973         else {
974                 if (ar_channels && !(ar_channels->flag & RGN_FLAG_HIDDEN)) {
975                         ar_channels->flag |= RGN_FLAG_HIDDEN;
976                         ar_channels->v2d.flag &= ~V2D_IS_INITIALISED;
977                         WM_event_remove_handlers((bContext *)C, &ar_tools->handlers);
978                         view_changed = TRUE;
979                 }
980                 if (ar_channels && ar_channels->alignment != RGN_ALIGN_NONE) {
981                         ar_channels->alignment = RGN_ALIGN_NONE;
982                         view_changed = TRUE;
983                 }
984         }
985
986         if (view_changed) {
987                 ED_area_initialize(wm, window, sa);
988                 ED_area_tag_redraw(sa);
989         }
990
991         BKE_movieclip_user_set_frame(&sc->user, scene->r.cfra);
992 }
993
994 /********************* main region ********************/
995
996 /* sets up the fields of the View2D from zoom and offset */
997 static void movieclip_main_area_set_view2d(SpaceClip *sc, ARegion *ar)
998 {
999         MovieClip *clip = ED_space_clip(sc);
1000         float x1, y1, w, h;
1001         int width, height, winx, winy;
1002
1003         ED_space_clip_size(sc, &width, &height);
1004
1005         w = width;
1006         h = height;
1007
1008         if (clip)
1009                 h *= clip->aspy / clip->aspx / clip->tracking.camera.pixel_aspect;
1010
1011         winx = ar->winrct.xmax - ar->winrct.xmin + 1;
1012         winy = ar->winrct.ymax - ar->winrct.ymin + 1;
1013
1014         ar->v2d.tot.xmin = 0;
1015         ar->v2d.tot.ymin = 0;
1016         ar->v2d.tot.xmax = w;
1017         ar->v2d.tot.ymax = h;
1018
1019         ar->v2d.mask.xmin = ar->v2d.mask.ymin = 0;
1020         ar->v2d.mask.xmax = winx;
1021         ar->v2d.mask.ymax = winy;
1022
1023         /* which part of the image space do we see? */
1024         x1 = ar->winrct.xmin + (winx - sc->zoom * w) / 2.0f;
1025         y1 = ar->winrct.ymin + (winy - sc->zoom * h) / 2.0f;
1026
1027         x1 -= sc->zoom * sc->xof;
1028         y1 -= sc->zoom * sc->yof;
1029
1030         /* relative display right */
1031         ar->v2d.cur.xmin = (ar->winrct.xmin - (float)x1) / sc->zoom;
1032         ar->v2d.cur.xmax = ar->v2d.cur.xmin + ((float)winx / sc->zoom);
1033
1034         /* relative display left */
1035         ar->v2d.cur.ymin = (ar->winrct.ymin - (float)y1) / sc->zoom;
1036         ar->v2d.cur.ymax = ar->v2d.cur.ymin + ((float)winy / sc->zoom);
1037
1038         /* normalize 0.0..1.0 */
1039         ar->v2d.cur.xmin /= w;
1040         ar->v2d.cur.xmax /= w;
1041         ar->v2d.cur.ymin /= h;
1042         ar->v2d.cur.ymax /= h;
1043 }
1044
1045 /* add handlers, stuff you only do once or on area/region changes */
1046 static void clip_main_area_init(wmWindowManager *wm, ARegion *ar)
1047 {
1048         wmKeyMap *keymap;
1049
1050         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
1051
1052         /* own keymap */
1053         keymap= WM_keymap_find(wm->defaultconf, "Mask Editor", 0, 0);
1054         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
1055
1056         keymap = WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0);
1057         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
1058
1059         keymap = WM_keymap_find(wm->defaultconf, "Clip Editor", SPACE_CLIP, 0);
1060         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
1061 }
1062
1063 static void clip_main_area_draw(const bContext *C, ARegion *ar)
1064 {
1065         /* draw entirely, view changes should be handled here */
1066         SpaceClip *sc = CTX_wm_space_clip(C);
1067         Scene *scene = CTX_data_scene(C);
1068         MovieClip *clip = ED_space_clip(sc);
1069
1070         /* if tracking is in progress, we should synchronize framenr from clipuser
1071          * so latest tracked frame would be shown */
1072         if (clip && clip->tracking_context)
1073                 BKE_tracking_sync_user(&sc->user, clip->tracking_context);
1074
1075         if (sc->flag & SC_LOCK_SELECTION) {
1076                 ImBuf *tmpibuf = NULL;
1077
1078                 if (clip && clip->tracking.stabilization.flag & TRACKING_2D_STABILIZATION) {
1079                         tmpibuf = ED_space_clip_get_stable_buffer(sc, NULL, NULL, NULL);
1080                 }
1081
1082                 if (ED_clip_view_selection(sc, ar, 0)) {
1083                         sc->xof += sc->xlockof;
1084                         sc->yof += sc->ylockof;
1085                 }
1086
1087                 if (tmpibuf)
1088                         IMB_freeImBuf(tmpibuf);
1089         }
1090
1091         /* clear and setup matrix */
1092         UI_ThemeClearColor(TH_BACK);
1093         glClear(GL_COLOR_BUFFER_BIT);
1094
1095         /* data... */
1096         movieclip_main_area_set_view2d(sc, ar);
1097
1098         clip_draw_main(sc, ar, scene);
1099
1100         /* Grease Pencil */
1101         clip_draw_grease_pencil((bContext *)C, 1);
1102
1103         if(sc->mode == SC_MODE_MASKEDITING) {
1104                 int x, y;
1105                 int width, height;
1106                 float zoomx, zoomy, aspx, aspy;
1107
1108                 /* frame image */
1109                 float maxdim;
1110                 float xofs, yofs;
1111
1112                 /* find window pixel coordinates of origin */
1113                 UI_view2d_to_region_no_clip(&ar->v2d, 0.0f, 0.0f, &x, &y);
1114
1115                 ED_space_clip_size(sc, &width, &height);
1116                 ED_space_clip_zoom(sc, ar, &zoomx, &zoomy);
1117                 ED_space_clip_aspect(sc, &aspx, &aspy);
1118
1119                 /* frame the image */
1120                 maxdim = maxf(width, height);
1121                 if (width == height) {
1122                         xofs = yofs = 0;
1123                 }
1124                 else if (width < height) {
1125                         xofs = ((height - width) / -2.0f) * zoomx;
1126                         yofs = 0.0f;
1127                 }
1128                 else { /* (width > height) */
1129                         xofs = 0.0f;
1130                         yofs = ((width - height) / -2.0f) * zoomy;
1131                 }
1132
1133                 /* apply transformation so mask editing tools will assume drawing from the origin in normalized space */
1134                 glPushMatrix();
1135                 glTranslatef(x + xofs, y + yofs, 0);
1136                 glScalef(maxdim * zoomx, maxdim * zoomy, 0);
1137                 glMultMatrixf(sc->stabmat);
1138
1139                 ED_mask_draw((bContext *)C);
1140
1141                 ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
1142
1143                 glPopMatrix();
1144         }
1145
1146         /* reset view matrix */
1147         UI_view2d_view_restore(C);
1148
1149         /* draw Grease Pencil - screen space only */
1150         clip_draw_grease_pencil((bContext *)C, 0);
1151 }
1152
1153 static void clip_main_area_listener(ARegion *ar, wmNotifier *wmn)
1154 {
1155         /* context changes */
1156         switch (wmn->category) {
1157                 case NC_SCREEN:
1158                         if (wmn->data == ND_GPENCIL)
1159                                 ED_region_tag_redraw(ar);
1160                 break;
1161         }
1162 }
1163
1164 /****************** preview region ******************/
1165
1166 static void clip_preview_area_init(wmWindowManager *wm, ARegion *ar)
1167 {
1168         wmKeyMap *keymap;
1169
1170         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
1171
1172         /* own keymap */
1173         keymap = WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0);
1174         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
1175
1176         keymap = WM_keymap_find(wm->defaultconf, "Clip Graph Editor", SPACE_CLIP, 0);
1177         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
1178 }
1179
1180 static void graph_area_draw(const bContext *C, ARegion *ar)
1181 {
1182         View2D *v2d = &ar->v2d;
1183         View2DScrollers *scrollers;
1184         SpaceClip *sc = CTX_wm_space_clip(C);
1185         Scene *scene = CTX_data_scene(C);
1186         short unitx, unity;
1187
1188         if (sc->flag & SC_LOCK_TIMECURSOR)
1189                 ED_clip_graph_center_current_frame(scene, ar);
1190
1191         /* clear and setup matrix */
1192         UI_ThemeClearColor(TH_BACK);
1193         glClear(GL_COLOR_BUFFER_BIT);
1194
1195         UI_view2d_view_ortho(v2d);
1196
1197         /* data... */
1198         clip_draw_graph(sc, ar, scene);
1199
1200         /* reset view matrix */
1201         UI_view2d_view_restore(C);
1202
1203         /* scrollers */
1204         unitx = (sc->flag & SC_SHOW_SECONDS)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
1205         unity = V2D_UNIT_VALUES;
1206         scrollers = UI_view2d_scrollers_calc(C, v2d, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP);
1207         UI_view2d_scrollers_draw(C, v2d, scrollers);
1208         UI_view2d_scrollers_free(scrollers);
1209 }
1210
1211 static void dopesheet_area_draw(const bContext *C, ARegion *ar)
1212 {
1213         Scene *scene = CTX_data_scene(C);
1214         SpaceClip *sc = CTX_wm_space_clip(C);
1215         MovieClip *clip = ED_space_clip(sc);
1216         View2D *v2d = &ar->v2d;
1217         View2DGrid *grid;
1218         View2DScrollers *scrollers;
1219         short unit = 0;
1220
1221         if (clip)
1222                 BKE_tracking_dopesheet_update(&clip->tracking, sc->dope_sort, sc->dope_flag & SC_DOPE_SORT_INVERSE);
1223
1224         /* clear and setup matrix */
1225         UI_ThemeClearColor(TH_BACK);
1226         glClear(GL_COLOR_BUFFER_BIT);
1227
1228         UI_view2d_view_ortho(v2d);
1229
1230         /* time grid */
1231         unit = (sc->flag & SC_SHOW_SECONDS)? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
1232         grid = UI_view2d_grid_calc(CTX_data_scene(C), v2d, unit, V2D_GRID_CLAMP,
1233                                    V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy);
1234         UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
1235         UI_view2d_grid_free(grid);
1236
1237         /* data... */
1238         clip_draw_dopesheet_main(sc, ar, scene);
1239
1240         /* reset view matrix */
1241         UI_view2d_view_restore(C);
1242
1243         /* scrollers */
1244         scrollers = UI_view2d_scrollers_calc(C, v2d, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
1245         UI_view2d_scrollers_draw(C, v2d, scrollers);
1246         UI_view2d_scrollers_free(scrollers);
1247 }
1248
1249 static void clip_preview_area_draw(const bContext *C, ARegion *ar)
1250 {
1251         SpaceClip *sc = CTX_wm_space_clip(C);
1252
1253         if (sc->view == SC_VIEW_GRAPH)
1254                 graph_area_draw(C, ar);
1255         else if (sc->view == SC_VIEW_DOPESHEET)
1256                 dopesheet_area_draw(C, ar);
1257 }
1258
1259 static void clip_preview_area_listener(ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
1260 {
1261 }
1262
1263 /****************** channels region ******************/
1264
1265 static void clip_channels_area_init(wmWindowManager *wm, ARegion *ar)
1266 {
1267         wmKeyMap *keymap;
1268
1269         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
1270
1271         keymap = WM_keymap_find(wm->defaultconf, "Clip Dopesheet Editor", SPACE_CLIP, 0);
1272         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
1273 }
1274
1275 static void clip_channels_area_draw(const bContext *C, ARegion *ar)
1276 {
1277         SpaceClip *sc = CTX_wm_space_clip(C);
1278         MovieClip *clip = ED_space_clip(sc);
1279         View2D *v2d = &ar->v2d;
1280         View2DScrollers *scrollers;
1281
1282         if (clip)
1283                 BKE_tracking_dopesheet_update(&clip->tracking, sc->dope_sort, sc->dope_flag & SC_DOPE_SORT_INVERSE);
1284
1285         /* clear and setup matrix */
1286         UI_ThemeClearColor(TH_BACK);
1287         glClear(GL_COLOR_BUFFER_BIT);
1288
1289         UI_view2d_view_ortho(v2d);
1290
1291         /* data... */
1292         clip_draw_dopesheet_channels(C, ar);
1293
1294         /* reset view matrix */
1295         UI_view2d_view_restore(C);
1296
1297         /* scrollers */
1298         scrollers = UI_view2d_scrollers_calc(C, v2d, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
1299         UI_view2d_scrollers_draw(C, v2d, scrollers);
1300         UI_view2d_scrollers_free(scrollers);
1301 }
1302
1303 static void clip_channels_area_listener(ARegion *UNUSED(ar), wmNotifier *UNUSED(wmn))
1304 {
1305 }
1306
1307 /****************** header region ******************/
1308
1309 /* add handlers, stuff you only do once or on area/region changes */
1310 static void clip_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar)
1311 {
1312         ED_region_header_init(ar);
1313 }
1314
1315 static void clip_header_area_draw(const bContext *C, ARegion *ar)
1316 {
1317         ED_region_header(C, ar);
1318 }
1319
1320 static void clip_header_area_listener(ARegion *ar, wmNotifier *wmn)
1321 {
1322         /* context changes */
1323         switch (wmn->category) {
1324                 case NC_SCENE:
1325                         switch (wmn->data) {
1326                                 /* for proportional editmode only */
1327                                 case ND_TOOLSETTINGS:
1328                                         /* TODO - should do this when in mask mode only but no datas available */
1329                                         // if(sc->mode == SC_MODE_MASKEDITING)
1330                                         {
1331                                                 ED_region_tag_redraw(ar);
1332                                         }
1333                                         break;
1334                         }
1335                         break;
1336         }
1337 }
1338
1339
1340 /****************** tools region ******************/
1341
1342 /* add handlers, stuff you only do once or on area/region changes */
1343 static void clip_tools_area_init(wmWindowManager *wm, ARegion *ar)
1344 {
1345         ED_region_panels_init(wm, ar);
1346 }
1347
1348 static void clip_tools_area_draw(const bContext *C, ARegion *ar)
1349 {
1350         ED_region_panels(C, ar, 1, NULL, -1);
1351 }
1352
1353 /****************** tool properties region ******************/
1354
1355 static void clip_props_area_listener(ARegion *ar, wmNotifier *wmn)
1356 {
1357         /* context changes */
1358         switch (wmn->category) {
1359                 case NC_WM:
1360                         if (wmn->data == ND_HISTORY)
1361                                 ED_region_tag_redraw(ar);
1362                         break;
1363                 case NC_SCENE:
1364                         if (wmn->data == ND_MODE)
1365                                 ED_region_tag_redraw(ar);
1366                         break;
1367                 case NC_SPACE:
1368                         if (wmn->data == ND_SPACE_CLIP)
1369                                 ED_region_tag_redraw(ar);
1370                         break;
1371                 case NC_SCREEN:
1372                         if (wmn->data == ND_GPENCIL)
1373                                 ED_region_tag_redraw(ar);
1374                         break;
1375         }
1376 }
1377
1378 /****************** properties region ******************/
1379
1380 /* add handlers, stuff you only do once or on area/region changes */
1381 static void clip_properties_area_init(wmWindowManager *wm, ARegion *ar)
1382 {
1383         wmKeyMap *keymap;
1384
1385         ED_region_panels_init(wm, ar);
1386
1387         keymap = WM_keymap_find(wm->defaultconf, "Clip", SPACE_CLIP, 0);
1388         WM_event_add_keymap_handler(&ar->handlers, keymap);
1389 }
1390
1391 static void clip_properties_area_draw(const bContext *C, ARegion *ar)
1392 {
1393         SpaceClip *sc = CTX_wm_space_clip(C);
1394
1395         BKE_movieclip_update_scopes(sc->clip, &sc->user, &sc->scopes);
1396
1397         ED_region_panels(C, ar, 1, NULL, -1);
1398 }
1399
1400 static void clip_properties_area_listener(ARegion *ar, wmNotifier *wmn)
1401 {
1402         /* context changes */
1403         switch (wmn->category) {
1404                 case NC_SCREEN:
1405                         if (wmn->data == ND_GPENCIL)
1406                                 ED_region_tag_redraw(ar);
1407                         break;
1408                 case NC_BRUSH:
1409                         if (wmn->action == NA_EDITED)
1410                                 ED_region_tag_redraw(ar);
1411                         break;
1412         }
1413 }
1414
1415 /********************* registration ********************/
1416
1417 /* only called once, from space/spacetypes.c */
1418 void ED_spacetype_clip(void)
1419 {
1420         SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype clip");
1421         ARegionType *art;
1422
1423         st->spaceid = SPACE_CLIP;
1424         strncpy(st->name, "Clip", BKE_ST_MAXNAME);
1425
1426         st->new = clip_new;
1427         st->free = clip_free;
1428         st->init = clip_init;
1429         st->duplicate = clip_duplicate;
1430         st->operatortypes = clip_operatortypes;
1431         st->keymap = clip_keymap;
1432         st->listener = clip_listener;
1433         st->context = clip_context;
1434         st->dropboxes = clip_dropboxes;
1435         st->refresh = clip_refresh;
1436
1437         /* regions: main window */
1438         art = MEM_callocN(sizeof(ARegionType), "spacetype clip region");
1439         art->regionid = RGN_TYPE_WINDOW;
1440         art->init = clip_main_area_init;
1441         art->draw = clip_main_area_draw;
1442         art->listener = clip_main_area_listener;
1443         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI | ED_KEYMAP_GPENCIL;
1444
1445         BLI_addhead(&st->regiontypes, art);
1446
1447         /* preview */
1448         art = MEM_callocN(sizeof(ARegionType), "spacetype clip region preview");
1449         art->regionid = RGN_TYPE_PREVIEW;
1450         art->prefsizey = 240;
1451         art->init = clip_preview_area_init;
1452         art->draw = clip_preview_area_draw;
1453         art->listener = clip_preview_area_listener;
1454         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI | ED_KEYMAP_VIEW2D;
1455
1456         BLI_addhead(&st->regiontypes, art);
1457
1458         /* regions: properties */
1459         art = MEM_callocN(sizeof(ARegionType), "spacetype clip region properties");
1460         art->regionid = RGN_TYPE_UI;
1461         art->prefsizex = UI_COMPACT_PANEL_WIDTH;
1462         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI;
1463         art->init = clip_properties_area_init;
1464         art->draw = clip_properties_area_draw;
1465         art->listener = clip_properties_area_listener;
1466         BLI_addhead(&st->regiontypes, art);
1467         ED_clip_buttons_register(art);
1468
1469         /* regions: tools */
1470         art = MEM_callocN(sizeof(ARegionType), "spacetype clip region tools");
1471         art->regionid = RGN_TYPE_TOOLS;
1472         art->prefsizex = UI_COMPACT_PANEL_WIDTH;
1473         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI;
1474         art->listener = clip_props_area_listener;
1475         art->init = clip_tools_area_init;
1476         art->draw = clip_tools_area_draw;
1477
1478         BLI_addhead(&st->regiontypes, art);
1479
1480         /* tool properties */
1481         art = MEM_callocN(sizeof(ARegionType), "spacetype clip tool properties region");
1482         art->regionid = RGN_TYPE_TOOL_PROPS;
1483         art->prefsizex = 0;
1484         art->prefsizey = 120;
1485         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI;
1486         art->listener = clip_props_area_listener;
1487         art->init = clip_tools_area_init;
1488         art->draw = clip_tools_area_draw;
1489         ED_clip_tool_props_register(art);
1490
1491         BLI_addhead(&st->regiontypes, art);
1492
1493         /* regions: header */
1494         art = MEM_callocN(sizeof(ARegionType), "spacetype clip region");
1495         art->regionid = RGN_TYPE_HEADER;
1496         art->prefsizey = HEADERY;
1497         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
1498
1499         art->init = clip_header_area_init;
1500         art->draw = clip_header_area_draw;
1501         art->listener = clip_header_area_listener;
1502
1503         BLI_addhead(&st->regiontypes, art);
1504
1505         BKE_spacetype_register(st);
1506
1507         /* channels */
1508         art = MEM_callocN(sizeof(ARegionType), "spacetype clip channels region");
1509         art->regionid = RGN_TYPE_CHANNELS;
1510         art->prefsizex = UI_COMPACT_PANEL_WIDTH;
1511         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI;
1512         art->listener = clip_channels_area_listener;
1513         art->init = clip_channels_area_init;
1514         art->draw = clip_channels_area_draw;
1515
1516         BLI_addhead(&st->regiontypes, art);
1517 }