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