Cleanup: quiet undeclared variable warnings
[blender.git] / source / blender / editors / space_clip / space_clip.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  *
16  * The Original Code is Copyright (C) 2011 Blender Foundation.
17  * All rights reserved.
18  */
19
20 /** \file
21  * \ingroup spclip
22  */
23
24 #include <string.h>
25 #include <stdio.h>
26
27 #include "DNA_scene_types.h"
28 #include "DNA_mask_types.h"
29 #include "DNA_movieclip_types.h"
30 #include "DNA_view3d_types.h"  /* for pivot point */
31
32 #include "MEM_guardedalloc.h"
33
34 #include "BLI_blenlib.h"
35 #include "BLI_utildefines.h"
36 #include "BLI_math.h"
37
38 #include "BKE_context.h"
39 #include "BKE_library.h"
40 #include "BKE_movieclip.h"
41 #include "BKE_tracking.h"
42 #include "BKE_screen.h"
43
44 #include "IMB_imbuf_types.h"
45
46 #include "ED_anim_api.h" /* for timeline cursor drawing */
47 #include "ED_mask.h"
48 #include "ED_space_api.h"
49 #include "ED_screen.h"
50 #include "ED_select_utils.h"
51 #include "ED_clip.h"
52 #include "ED_transform.h"
53 #include "ED_uvedit.h"  /* just for ED_image_draw_cursor */
54
55 #include "IMB_imbuf.h"
56
57 #include "GPU_glew.h"
58 #include "GPU_matrix.h"
59 #include "GPU_framebuffer.h"
60
61 #include "WM_api.h"
62 #include "WM_types.h"
63
64 #include "UI_interface.h"
65 #include "UI_resources.h"
66 #include "UI_view2d.h"
67
68 #include "RNA_access.h"
69
70
71 #include "clip_intern.h"  /* own include */
72
73 static void init_preview_region(const Scene *scene, const ScrArea *sa, const SpaceClip *sc, ARegion *ar)
74 {
75         ar->regiontype = RGN_TYPE_PREVIEW;
76         ar->alignment = RGN_ALIGN_TOP;
77         ar->flag |= RGN_FLAG_HIDDEN;
78
79         if (sc->view == SC_VIEW_DOPESHEET) {
80                 ar->v2d.tot.xmin = -10.0f;
81                 ar->v2d.tot.ymin = (float)(-sa->winy) / 3.0f;
82                 ar->v2d.tot.xmax = (float)(sa->winx);
83                 ar->v2d.tot.ymax = 0.0f;
84
85                 ar->v2d.cur = ar->v2d.tot;
86
87                 ar->v2d.min[0] = 0.0f;
88                 ar->v2d.min[1] = 0.0f;
89
90                 ar->v2d.max[0] = MAXFRAMEF;
91                 ar->v2d.max[1] = FLT_MAX;
92
93                 ar->v2d.minzoom = 0.01f;
94                 ar->v2d.maxzoom = 50;
95                 ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
96                 ar->v2d.scroll |= (V2D_SCROLL_RIGHT);
97                 ar->v2d.keepzoom = V2D_LOCKZOOM_Y;
98                 ar->v2d.keepofs = V2D_KEEPOFS_Y;
99                 ar->v2d.align = V2D_ALIGN_NO_POS_Y;
100                 ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
101         }
102         else {
103                 ar->v2d.tot.xmin = 0.0f;
104                 ar->v2d.tot.ymin = -10.0f;
105                 ar->v2d.tot.xmax = (float)scene->r.efra;
106                 ar->v2d.tot.ymax = 10.0f;
107
108                 ar->v2d.cur = ar->v2d.tot;
109
110                 ar->v2d.min[0] = FLT_MIN;
111                 ar->v2d.min[1] = FLT_MIN;
112
113                 ar->v2d.max[0] = MAXFRAMEF;
114                 ar->v2d.max[1] = FLT_MAX;
115
116                 ar->v2d.scroll = (V2D_SCROLL_BOTTOM | V2D_SCROLL_SCALE_HORIZONTAL);
117                 ar->v2d.scroll |= (V2D_SCROLL_LEFT | V2D_SCROLL_SCALE_VERTICAL);
118
119                 ar->v2d.minzoom = 0.0f;
120                 ar->v2d.maxzoom = 0.0f;
121                 ar->v2d.keepzoom = 0;
122                 ar->v2d.keepofs = 0;
123                 ar->v2d.align = 0;
124                 ar->v2d.flag = 0;
125
126                 ar->v2d.keeptot = 0;
127         }
128 }
129
130 static void reinit_preview_region(const bContext *C, ARegion *ar)
131 {
132         Scene *scene = CTX_data_scene(C);
133         ScrArea *sa = CTX_wm_area(C);
134         SpaceClip *sc = CTX_wm_space_clip(C);
135
136         if (sc->view == SC_VIEW_DOPESHEET) {
137                 if ((ar->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL) == 0)
138                         init_preview_region(scene, sa, sc, ar);
139         }
140         else {
141                 if (ar->v2d.flag & V2D_VIEWSYNC_AREA_VERTICAL)
142                         init_preview_region(scene, sa, sc, ar);
143         }
144 }
145
146 static ARegion *ED_clip_has_preview_region(const bContext *C, ScrArea *sa)
147 {
148         ARegion *ar, *arnew;
149
150         ar = BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW);
151         if (ar)
152                 return ar;
153
154         /* add subdiv level; after header */
155         ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
156
157         /* is error! */
158         if (ar == NULL)
159                 return NULL;
160
161         arnew = MEM_callocN(sizeof(ARegion), "clip preview region");
162
163         BLI_insertlinkbefore(&sa->regionbase, ar, arnew);
164         init_preview_region(CTX_data_scene(C), sa, CTX_wm_space_clip(C), arnew);
165
166         return arnew;
167 }
168
169 static ARegion *ED_clip_has_channels_region(ScrArea *sa)
170 {
171         ARegion *ar, *arnew;
172
173         ar = BKE_area_find_region_type(sa, RGN_TYPE_CHANNELS);
174         if (ar)
175                 return ar;
176
177         /* add subdiv level; after header */
178         ar = BKE_area_find_region_type(sa, RGN_TYPE_PREVIEW);
179
180         /* is error! */
181         if (ar == NULL)
182                 return NULL;
183
184         arnew = MEM_callocN(sizeof(ARegion), "clip channels region");
185
186         BLI_insertlinkbefore(&sa->regionbase, ar, arnew);
187         arnew->regiontype = RGN_TYPE_CHANNELS;
188         arnew->alignment = RGN_ALIGN_LEFT;
189
190         arnew->v2d.scroll = V2D_SCROLL_BOTTOM;
191         arnew->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
192
193         return arnew;
194 }
195
196 static void clip_scopes_tag_refresh(ScrArea *sa)
197 {
198         SpaceClip *sc = (SpaceClip *)sa->spacedata.first;
199         ARegion *ar;
200
201         if (sc->mode != SC_MODE_TRACKING)
202                 return;
203
204         /* only while properties are visible */
205         for (ar = sa->regionbase.first; ar; ar = ar->next) {
206                 if (ar->regiontype == RGN_TYPE_UI && ar->flag & RGN_FLAG_HIDDEN)
207                         return;
208         }
209
210         sc->scopes.ok = false;
211 }
212
213 static void clip_scopes_check_gpencil_change(ScrArea *sa)
214 {
215         SpaceClip *sc = (SpaceClip *)sa->spacedata.first;
216
217         if (sc->gpencil_src == SC_GPENCIL_SRC_TRACK) {
218                 clip_scopes_tag_refresh(sa);
219         }
220 }
221
222 static void clip_area_sync_frame_from_scene(ScrArea *sa, Scene *scene)
223 {
224         SpaceClip *space_clip = (SpaceClip *)sa->spacedata.first;
225         BKE_movieclip_user_set_frame(&space_clip->user, scene->r.cfra);
226 }
227
228 /* ******************** default callbacks for clip space ***************** */
229
230 static SpaceLink *clip_new(const ScrArea *sa, const Scene *scene)
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_ANNOTATION;
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 = (U.uiflag & USER_HEADER_BOTTOM) ? RGN_ALIGN_BOTTOM : RGN_ALIGN_TOP;
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         /* properties view */
259         ar = MEM_callocN(sizeof(ARegion), "properties for clip");
260
261         BLI_addtail(&sc->regionbase, ar);
262         ar->regiontype = RGN_TYPE_UI;
263         ar->alignment = RGN_ALIGN_RIGHT;
264
265         /* channels view */
266         ar = MEM_callocN(sizeof(ARegion), "channels for clip");
267
268         BLI_addtail(&sc->regionbase, ar);
269         ar->regiontype = RGN_TYPE_CHANNELS;
270         ar->alignment = RGN_ALIGN_LEFT;
271
272         ar->v2d.scroll = V2D_SCROLL_BOTTOM;
273         ar->v2d.flag = V2D_VIEWSYNC_AREA_VERTICAL;
274
275         /* preview view */
276         ar = MEM_callocN(sizeof(ARegion), "preview for clip");
277
278         BLI_addtail(&sc->regionbase, ar);
279         init_preview_region(scene, sa, sc, ar);
280
281         /* main region */
282         ar = MEM_callocN(sizeof(ARegion), "main region for clip");
283
284         BLI_addtail(&sc->regionbase, ar);
285         ar->regiontype = RGN_TYPE_WINDOW;
286
287         return (SpaceLink *) sc;
288 }
289
290 /* not spacelink itself */
291 static void clip_free(SpaceLink *sl)
292 {
293         SpaceClip *sc = (SpaceClip *) sl;
294
295         sc->clip = NULL;
296
297         if (sc->scopes.track_preview)
298                 IMB_freeImBuf(sc->scopes.track_preview);
299
300         if (sc->scopes.track_search)
301                 IMB_freeImBuf(sc->scopes.track_search);
302 }
303
304 /* spacetype; init callback */
305 static void clip_init(struct wmWindowManager *UNUSED(wm), ScrArea *sa)
306 {
307         ListBase *lb = WM_dropboxmap_find("Clip", SPACE_CLIP, 0);
308
309         /* add drop boxes */
310         WM_event_add_dropbox_handler(&sa->handlers, lb);
311 }
312
313 static SpaceLink *clip_duplicate(SpaceLink *sl)
314 {
315         SpaceClip *scn = MEM_dupallocN(sl);
316
317         /* clear or remove stuff from old */
318         scn->scopes.track_search = NULL;
319         scn->scopes.track_preview = NULL;
320         scn->scopes.ok = false;
321
322         return (SpaceLink *)scn;
323 }
324
325 static void clip_listener(wmWindow *UNUSED(win), ScrArea *sa, wmNotifier *wmn, Scene *scene)
326 {
327         /* context changes */
328         switch (wmn->category) {
329                 case NC_SCENE:
330                         switch (wmn->data) {
331                                 case ND_FRAME:
332                                         clip_scopes_tag_refresh(sa);
333                                         ATTR_FALLTHROUGH;
334
335                                 case ND_FRAME_RANGE:
336                                         ED_area_tag_redraw(sa);
337                                         break;
338                         }
339                         break;
340                 case NC_MOVIECLIP:
341                         switch (wmn->data) {
342                                 case ND_DISPLAY:
343                                 case ND_SELECT:
344                                         clip_scopes_tag_refresh(sa);
345                                         ED_area_tag_redraw(sa);
346                                         break;
347                         }
348                         switch (wmn->action) {
349                                 case NA_REMOVED:
350                                 case NA_EDITED:
351                                 case NA_EVALUATED:
352                                         /* fall-through */
353
354                                 case NA_SELECTED:
355                                         clip_scopes_tag_refresh(sa);
356                                         ED_area_tag_redraw(sa);
357                                         break;
358                         }
359                         break;
360                 case NC_MASK:
361                         switch (wmn->data) {
362                                 case ND_SELECT:
363                                 case ND_DATA:
364                                 case ND_DRAW:
365                                         ED_area_tag_redraw(sa);
366                                         break;
367                         }
368                         switch (wmn->action) {
369                                 case NA_SELECTED:
370                                         ED_area_tag_redraw(sa);
371                                         break;
372                                 case NA_EDITED:
373                                         ED_area_tag_redraw(sa);
374                                         break;
375                         }
376                         break;
377                 case NC_GEOM:
378                         switch (wmn->data) {
379                                 case ND_SELECT:
380                                         clip_scopes_tag_refresh(sa);
381                                         ED_area_tag_redraw(sa);
382                                         break;
383                         }
384                         break;
385                 case NC_SCREEN:
386                         switch (wmn->data) {
387                                 case ND_ANIMPLAY:
388                                         ED_area_tag_redraw(sa);
389                                         break;
390                                 case ND_LAYOUTSET:
391                                         clip_area_sync_frame_from_scene(sa, scene);
392                                         break;
393                         }
394                         break;
395                 case NC_SPACE:
396                         if (wmn->data == ND_SPACE_CLIP) {
397                                 clip_scopes_tag_refresh(sa);
398                                 ED_area_tag_redraw(sa);
399                         }
400                         break;
401                 case NC_GPENCIL:
402                         if (wmn->action == NA_EDITED) {
403                                 clip_scopes_check_gpencil_change(sa);
404                                 ED_area_tag_redraw(sa);
405                         }
406                         else if (wmn->data & ND_GPENCIL_EDITMODE) {
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 #ifdef WITH_INPUT_NDOF
429         WM_operatortype_append(CLIP_OT_view_ndof);
430 #endif
431         WM_operatortype_append(CLIP_OT_prefetch);
432         WM_operatortype_append(CLIP_OT_set_scene_frames);
433         WM_operatortype_append(CLIP_OT_cursor_set);
434
435         /* ** clip_toolbar.c ** */
436         WM_operatortype_append(CLIP_OT_tools);
437         WM_operatortype_append(CLIP_OT_properties);
438
439         /* ** tracking_ops.c ** */
440
441         /* navigation */
442         WM_operatortype_append(CLIP_OT_frame_jump);
443
444         /* set optical center to frame center */
445         WM_operatortype_append(CLIP_OT_set_center_principal);
446
447         /* selection */
448         WM_operatortype_append(CLIP_OT_select);
449         WM_operatortype_append(CLIP_OT_select_all);
450         WM_operatortype_append(CLIP_OT_select_box);
451         WM_operatortype_append(CLIP_OT_select_lasso);
452         WM_operatortype_append(CLIP_OT_select_circle);
453         WM_operatortype_append(CLIP_OT_select_grouped);
454
455         /* markers */
456         WM_operatortype_append(CLIP_OT_add_marker);
457         WM_operatortype_append(CLIP_OT_add_marker_at_click);
458         WM_operatortype_append(CLIP_OT_slide_marker);
459         WM_operatortype_append(CLIP_OT_delete_track);
460         WM_operatortype_append(CLIP_OT_delete_marker);
461
462         /* track */
463         WM_operatortype_append(CLIP_OT_track_markers);
464         WM_operatortype_append(CLIP_OT_refine_markers);
465
466         /* solving */
467         WM_operatortype_append(CLIP_OT_solve_camera);
468         WM_operatortype_append(CLIP_OT_clear_solution);
469
470         WM_operatortype_append(CLIP_OT_disable_markers);
471         WM_operatortype_append(CLIP_OT_hide_tracks);
472         WM_operatortype_append(CLIP_OT_hide_tracks_clear);
473         WM_operatortype_append(CLIP_OT_lock_tracks);
474
475         WM_operatortype_append(CLIP_OT_set_solver_keyframe);
476
477         /* orientation */
478         WM_operatortype_append(CLIP_OT_set_origin);
479         WM_operatortype_append(CLIP_OT_set_plane);
480         WM_operatortype_append(CLIP_OT_set_axis);
481         WM_operatortype_append(CLIP_OT_set_scale);
482         WM_operatortype_append(CLIP_OT_set_solution_scale);
483         WM_operatortype_append(CLIP_OT_apply_solution_scale);
484
485         /* detect */
486         WM_operatortype_append(CLIP_OT_detect_features);
487
488         /* stabilization */
489         WM_operatortype_append(CLIP_OT_stabilize_2d_add);
490         WM_operatortype_append(CLIP_OT_stabilize_2d_remove);
491         WM_operatortype_append(CLIP_OT_stabilize_2d_select);
492         WM_operatortype_append(CLIP_OT_stabilize_2d_rotation_add);
493         WM_operatortype_append(CLIP_OT_stabilize_2d_rotation_remove);
494         WM_operatortype_append(CLIP_OT_stabilize_2d_rotation_select);
495
496         /* clean-up */
497         WM_operatortype_append(CLIP_OT_clear_track_path);
498         WM_operatortype_append(CLIP_OT_join_tracks);
499         WM_operatortype_append(CLIP_OT_track_copy_color);
500
501         WM_operatortype_append(CLIP_OT_clean_tracks);
502
503         /* object tracking */
504         WM_operatortype_append(CLIP_OT_tracking_object_new);
505         WM_operatortype_append(CLIP_OT_tracking_object_remove);
506
507         /* clipboard */
508         WM_operatortype_append(CLIP_OT_copy_tracks);
509         WM_operatortype_append(CLIP_OT_paste_tracks);
510
511         /* Plane tracker */
512         WM_operatortype_append(CLIP_OT_create_plane_track);
513         WM_operatortype_append(CLIP_OT_slide_plane_marker);
514
515         WM_operatortype_append(CLIP_OT_keyframe_insert);
516         WM_operatortype_append(CLIP_OT_keyframe_delete);
517
518         /* ** clip_graph_ops.c  ** */
519
520         /* graph editing */
521
522         /* selection */
523         WM_operatortype_append(CLIP_OT_graph_select);
524         WM_operatortype_append(CLIP_OT_graph_select_box);
525         WM_operatortype_append(CLIP_OT_graph_select_all_markers);
526
527         WM_operatortype_append(CLIP_OT_graph_delete_curve);
528         WM_operatortype_append(CLIP_OT_graph_delete_knot);
529         WM_operatortype_append(CLIP_OT_graph_view_all);
530         WM_operatortype_append(CLIP_OT_graph_center_current_frame);
531
532         WM_operatortype_append(CLIP_OT_graph_disable_markers);
533
534         /* ** clip_dopesheet_ops.c  ** */
535
536         WM_operatortype_append(CLIP_OT_dopesheet_select_channel);
537         WM_operatortype_append(CLIP_OT_dopesheet_view_all);
538 }
539
540 static void clip_keymap(struct wmKeyConfig *keyconf)
541 {
542         /* ******** Global hotkeys avalaible for all regions ******** */
543         WM_keymap_ensure(keyconf, "Clip", SPACE_CLIP, 0);
544
545         /* ******** Hotkeys avalaible for main region only ******** */
546         WM_keymap_ensure(keyconf, "Clip Editor", SPACE_CLIP, 0);
547 //      keymap->poll = ED_space_clip_tracking_poll;
548
549         /* ******** Hotkeys avalaible for preview region only ******** */
550         WM_keymap_ensure(keyconf, "Clip Graph Editor", SPACE_CLIP, 0);
551
552         /* ******** Hotkeys avalaible for channels region only ******** */
553         WM_keymap_ensure(keyconf, "Clip Dopesheet Editor", SPACE_CLIP, 0);
554 }
555
556 /* DO NOT make this static, this hides the symbol and breaks API generation script. */
557 extern const char *clip_context_dir[];  /* quiet warning. */
558 const char *clip_context_dir[] = {"edit_movieclip", "edit_mask", NULL};
559
560 static int clip_context(const bContext *C, const char *member, bContextDataResult *result)
561 {
562         SpaceClip *sc = CTX_wm_space_clip(C);
563
564         if (CTX_data_dir(member)) {
565                 CTX_data_dir_set(result, clip_context_dir);
566
567                 return true;
568         }
569         else if (CTX_data_equals(member, "edit_movieclip")) {
570                 if (sc->clip)
571                         CTX_data_id_pointer_set(result, &sc->clip->id);
572                 return true;
573         }
574         else if (CTX_data_equals(member, "edit_mask")) {
575                 if (sc->mask_info.mask)
576                         CTX_data_id_pointer_set(result, &sc->mask_info.mask->id);
577                 return true;
578         }
579
580         return false;
581 }
582
583 /* dropboxes */
584 static bool clip_drop_poll(bContext *UNUSED(C), wmDrag *drag, const wmEvent *UNUSED(event), const char **UNUSED(tooltip))
585 {
586         if (drag->type == WM_DRAG_PATH) {
587                 /* rule might not work? */
588                 if (ELEM(drag->icon, 0, ICON_FILE_IMAGE, ICON_FILE_MOVIE, ICON_FILE_BLANK)) {
589                         return true;
590                 }
591         }
592
593         return false;
594 }
595
596 static void clip_drop_copy(wmDrag *drag, wmDropBox *drop)
597 {
598         PointerRNA itemptr;
599         char dir[FILE_MAX], file[FILE_MAX];
600
601         BLI_split_dirfile(drag->path, dir, file, sizeof(dir), sizeof(file));
602
603         RNA_string_set(drop->ptr, "directory", dir);
604
605         RNA_collection_clear(drop->ptr, "files");
606         RNA_collection_add(drop->ptr, "files", &itemptr);
607         RNA_string_set(&itemptr, "name", file);
608 }
609
610 /* area+region dropbox definition */
611 static void clip_dropboxes(void)
612 {
613         ListBase *lb = WM_dropboxmap_find("Clip", SPACE_CLIP, 0);
614
615         WM_dropbox_add(lb, "CLIP_OT_open", clip_drop_poll, clip_drop_copy);
616 }
617
618 static void clip_refresh(const bContext *C, ScrArea *sa)
619 {
620         wmWindowManager *wm = CTX_wm_manager(C);
621         wmWindow *window = CTX_wm_window(C);
622         Scene *scene = CTX_data_scene(C);
623         SpaceClip *sc = (SpaceClip *)sa->spacedata.first;
624         ARegion *ar_main = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW);
625         ARegion *ar_tools = BKE_area_find_region_type(sa, RGN_TYPE_TOOLS);
626         ARegion *ar_preview = ED_clip_has_preview_region(C, sa);
627         ARegion *ar_properties = ED_clip_has_properties_region(sa);
628         ARegion *ar_channels = ED_clip_has_channels_region(sa);
629         bool main_visible = false, preview_visible = false, tools_visible = false;
630         bool properties_visible = false, channels_visible = false;
631         bool view_changed = false;
632
633         switch (sc->view) {
634                 case SC_VIEW_CLIP:
635                         main_visible = true;
636                         preview_visible = false;
637                         tools_visible = true;
638                         properties_visible = true;
639                         channels_visible = false;
640                         break;
641                 case SC_VIEW_GRAPH:
642                         main_visible = false;
643                         preview_visible = true;
644                         tools_visible = false;
645                         properties_visible = false;
646                         channels_visible = false;
647
648                         reinit_preview_region(C, ar_preview);
649                         break;
650                 case SC_VIEW_DOPESHEET:
651                         main_visible = false;
652                         preview_visible = true;
653                         tools_visible = false;
654                         properties_visible = false;
655                         channels_visible = true;
656
657                         reinit_preview_region(C, ar_preview);
658                         break;
659         }
660
661         if (main_visible) {
662                 if (ar_main && (ar_main->flag & RGN_FLAG_HIDDEN)) {
663                         ar_main->flag &= ~RGN_FLAG_HIDDEN;
664                         ar_main->v2d.flag &= ~V2D_IS_INITIALISED;
665                         view_changed = true;
666                 }
667
668                 if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) {
669                         ar_main->alignment = RGN_ALIGN_NONE;
670                         view_changed = true;
671                 }
672         }
673         else {
674                 if (ar_main && !(ar_main->flag & RGN_FLAG_HIDDEN)) {
675                         ar_main->flag |= RGN_FLAG_HIDDEN;
676                         ar_main->v2d.flag &= ~V2D_IS_INITIALISED;
677                         WM_event_remove_handlers((bContext *)C, &ar_main->handlers);
678                         view_changed = true;
679                 }
680                 if (ar_main && ar_main->alignment != RGN_ALIGN_NONE) {
681                         ar_main->alignment = RGN_ALIGN_NONE;
682                         view_changed = true;
683                 }
684         }
685
686         if (properties_visible) {
687                 if (ar_properties && (ar_properties->flag & RGN_FLAG_HIDDEN)) {
688                         ar_properties->flag &= ~RGN_FLAG_HIDDEN;
689                         ar_properties->v2d.flag &= ~V2D_IS_INITIALISED;
690                         view_changed = true;
691                 }
692                 if (ar_properties && ar_properties->alignment != RGN_ALIGN_RIGHT) {
693                         ar_properties->alignment = RGN_ALIGN_RIGHT;
694                         view_changed = true;
695                 }
696         }
697         else {
698                 if (ar_properties && !(ar_properties->flag & RGN_FLAG_HIDDEN)) {
699                         ar_properties->flag |= RGN_FLAG_HIDDEN;
700                         ar_properties->v2d.flag &= ~V2D_IS_INITIALISED;
701                         WM_event_remove_handlers((bContext *)C, &ar_properties->handlers);
702                         view_changed = true;
703                 }
704                 if (ar_properties && ar_properties->alignment != RGN_ALIGN_NONE) {
705                         ar_properties->alignment = RGN_ALIGN_NONE;
706                         view_changed = true;
707                 }
708         }
709
710         if (tools_visible) {
711                 if (ar_tools && (ar_tools->flag & RGN_FLAG_HIDDEN)) {
712                         ar_tools->flag &= ~RGN_FLAG_HIDDEN;
713                         ar_tools->v2d.flag &= ~V2D_IS_INITIALISED;
714                         view_changed = true;
715                 }
716                 if (ar_tools && ar_tools->alignment != RGN_ALIGN_LEFT) {
717                         ar_tools->alignment = RGN_ALIGN_LEFT;
718                         view_changed = true;
719                 }
720         }
721         else {
722                 if (ar_tools && !(ar_tools->flag & RGN_FLAG_HIDDEN)) {
723                         ar_tools->flag |= RGN_FLAG_HIDDEN;
724                         ar_tools->v2d.flag &= ~V2D_IS_INITIALISED;
725                         WM_event_remove_handlers((bContext *)C, &ar_tools->handlers);
726                         view_changed = true;
727                 }
728                 if (ar_tools && ar_tools->alignment != RGN_ALIGN_NONE) {
729                         ar_tools->alignment = RGN_ALIGN_NONE;
730                         view_changed = true;
731                 }
732         }
733
734         if (preview_visible) {
735                 if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) {
736                         ar_preview->flag &= ~RGN_FLAG_HIDDEN;
737                         ar_preview->v2d.flag &= ~V2D_IS_INITIALISED;
738                         ar_preview->v2d.cur = ar_preview->v2d.tot;
739                         view_changed = true;
740                 }
741                 if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) {
742                         ar_preview->alignment = RGN_ALIGN_NONE;
743                         view_changed = true;
744                 }
745         }
746         else {
747                 if (ar_preview && !(ar_preview->flag & RGN_FLAG_HIDDEN)) {
748                         ar_preview->flag |= RGN_FLAG_HIDDEN;
749                         ar_preview->v2d.flag &= ~V2D_IS_INITIALISED;
750                         WM_event_remove_handlers((bContext *)C, &ar_preview->handlers);
751                         view_changed = true;
752                 }
753                 if (ar_preview && ar_preview->alignment != RGN_ALIGN_NONE) {
754                         ar_preview->alignment = RGN_ALIGN_NONE;
755                         view_changed = true;
756                 }
757         }
758
759         if (channels_visible) {
760                 if (ar_channels && (ar_channels->flag & RGN_FLAG_HIDDEN)) {
761                         ar_channels->flag &= ~RGN_FLAG_HIDDEN;
762                         ar_channels->v2d.flag &= ~V2D_IS_INITIALISED;
763                         view_changed = true;
764                 }
765                 if (ar_channels && ar_channels->alignment != RGN_ALIGN_LEFT) {
766                         ar_channels->alignment = RGN_ALIGN_LEFT;
767                         view_changed = true;
768                 }
769         }
770         else {
771                 if (ar_channels && !(ar_channels->flag & RGN_FLAG_HIDDEN)) {
772                         ar_channels->flag |= RGN_FLAG_HIDDEN;
773                         ar_channels->v2d.flag &= ~V2D_IS_INITIALISED;
774                         WM_event_remove_handlers((bContext *)C, &ar_channels->handlers);
775                         view_changed = true;
776                 }
777                 if (ar_channels && ar_channels->alignment != RGN_ALIGN_NONE) {
778                         ar_channels->alignment = RGN_ALIGN_NONE;
779                         view_changed = true;
780                 }
781         }
782
783         if (view_changed) {
784                 ED_area_initialize(wm, window, sa);
785                 ED_area_tag_redraw(sa);
786         }
787
788         BKE_movieclip_user_set_frame(&sc->user, scene->r.cfra);
789 }
790
791 /********************* main region ********************/
792
793 /* sets up the fields of the View2D from zoom and offset */
794 static void movieclip_main_area_set_view2d(const bContext *C, ARegion *ar)
795 {
796         SpaceClip *sc = CTX_wm_space_clip(C);
797         float x1, y1, w, h, aspx, aspy;
798         int width, height, winx, winy;
799
800         ED_space_clip_get_size(sc, &width, &height);
801         ED_space_clip_get_aspect(sc, &aspx, &aspy);
802
803         w = width * aspx;
804         h = height * aspy;
805
806         winx = BLI_rcti_size_x(&ar->winrct) + 1;
807         winy = BLI_rcti_size_y(&ar->winrct) + 1;
808
809         ar->v2d.tot.xmin = 0;
810         ar->v2d.tot.ymin = 0;
811         ar->v2d.tot.xmax = w;
812         ar->v2d.tot.ymax = h;
813
814         ar->v2d.mask.xmin = ar->v2d.mask.ymin = 0;
815         ar->v2d.mask.xmax = winx;
816         ar->v2d.mask.ymax = winy;
817
818         /* which part of the image space do we see? */
819         x1 = ar->winrct.xmin + (winx - sc->zoom * w) / 2.0f;
820         y1 = ar->winrct.ymin + (winy - sc->zoom * h) / 2.0f;
821
822         x1 -= sc->zoom * sc->xof;
823         y1 -= sc->zoom * sc->yof;
824
825         /* relative display right */
826         ar->v2d.cur.xmin = (ar->winrct.xmin - (float)x1) / sc->zoom;
827         ar->v2d.cur.xmax = ar->v2d.cur.xmin + ((float)winx / sc->zoom);
828
829         /* relative display left */
830         ar->v2d.cur.ymin = (ar->winrct.ymin - (float)y1) / sc->zoom;
831         ar->v2d.cur.ymax = ar->v2d.cur.ymin + ((float)winy / sc->zoom);
832
833         /* normalize 0.0..1.0 */
834         ar->v2d.cur.xmin /= w;
835         ar->v2d.cur.xmax /= w;
836         ar->v2d.cur.ymin /= h;
837         ar->v2d.cur.ymax /= h;
838 }
839
840 /* add handlers, stuff you only do once or on area/region changes */
841 static void clip_main_region_init(wmWindowManager *wm, ARegion *ar)
842 {
843         wmKeyMap *keymap;
844
845         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_STANDARD, ar->winx, ar->winy);
846
847         /* mask polls mode */
848         keymap = WM_keymap_ensure(wm->defaultconf, "Mask Editing", 0, 0);
849         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
850
851         /* own keymap */
852         keymap = WM_keymap_ensure(wm->defaultconf, "Clip", SPACE_CLIP, 0);
853         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
854
855         keymap = WM_keymap_ensure(wm->defaultconf, "Clip Editor", SPACE_CLIP, 0);
856         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
857 }
858
859 static void clip_main_region_draw(const bContext *C, ARegion *ar)
860 {
861         /* draw entirely, view changes should be handled here */
862         SpaceClip *sc = CTX_wm_space_clip(C);
863         MovieClip *clip = ED_space_clip_get_clip(sc);
864         float aspx, aspy, zoomx, zoomy, x, y;
865         int width, height;
866         bool show_cursor = false;
867
868         /* if tracking is in progress, we should synchronize framenr from clipuser
869          * so latest tracked frame would be shown */
870         if (clip && clip->tracking_context)
871                 BKE_autotrack_context_sync_user(clip->tracking_context, &sc->user);
872
873         if (sc->flag & SC_LOCK_SELECTION) {
874                 ImBuf *tmpibuf = NULL;
875
876                 if (clip && clip->tracking.stabilization.flag & TRACKING_2D_STABILIZATION) {
877                         tmpibuf = ED_space_clip_get_stable_buffer(sc, NULL, NULL, NULL);
878                 }
879
880                 if (ED_clip_view_selection(C, ar, 0)) {
881                         sc->xof += sc->xlockof;
882                         sc->yof += sc->ylockof;
883                 }
884
885                 if (tmpibuf)
886                         IMB_freeImBuf(tmpibuf);
887         }
888
889         /* clear and setup matrix */
890         UI_ThemeClearColor(TH_BACK);
891         GPU_clear(GPU_COLOR_BIT);
892
893         /* data... */
894         movieclip_main_area_set_view2d(C, ar);
895
896         /* callback */
897         ED_region_draw_cb_draw(C, ar, REGION_DRAW_PRE_VIEW);
898
899         clip_draw_main(C, sc, ar);
900
901         /* TODO(sergey): would be nice to find a way to de-duplicate all this space conversions */
902         UI_view2d_view_to_region_fl(&ar->v2d, 0.0f, 0.0f, &x, &y);
903         ED_space_clip_get_size(sc, &width, &height);
904         ED_space_clip_get_zoom(sc, ar, &zoomx, &zoomy);
905         ED_space_clip_get_aspect(sc, &aspx, &aspy);
906
907         if (sc->mode == SC_MODE_MASKEDIT) {
908                 Mask *mask = CTX_data_edit_mask(C);
909                 if (mask && clip) {
910                         ScrArea *sa = CTX_wm_area(C);
911                         int mask_width, mask_height;
912                         ED_mask_get_size(sa, &mask_width, &mask_height);
913                         ED_mask_draw_region(mask, ar,
914                                             sc->mask_info.draw_flag,
915                                             sc->mask_info.draw_type,
916                                             sc->mask_info.overlay_mode,
917                                             mask_width, mask_height,
918                                             aspx, aspy,
919                                             true, true,
920                                             sc->stabmat, C);
921                 }
922         }
923
924         show_cursor |= sc->mode == SC_MODE_MASKEDIT;
925         show_cursor |= sc->around == V3D_AROUND_CURSOR;
926
927         if (show_cursor) {
928                 GPU_matrix_push();
929                 GPU_matrix_translate_2f(x, y);
930                 GPU_matrix_scale_2f(zoomx, zoomy);
931                 GPU_matrix_mul(sc->stabmat);
932                 GPU_matrix_scale_2f(width, height);
933                 ED_image_draw_cursor(ar, sc->cursor);
934                 GPU_matrix_pop();
935         }
936
937         clip_draw_cache_and_notes(C, sc, ar);
938
939         if (sc->flag & SC_SHOW_ANNOTATION) {
940                 /* Grease Pencil */
941                 clip_draw_grease_pencil((bContext *)C, true);
942         }
943
944         /* callback */
945         ED_region_draw_cb_draw(C, ar, REGION_DRAW_POST_VIEW);
946
947         /* reset view matrix */
948         UI_view2d_view_restore(C);
949
950         if (sc->flag & SC_SHOW_ANNOTATION) {
951                 /* draw Grease Pencil - screen space only */
952                 clip_draw_grease_pencil((bContext *)C, false);
953         }
954 }
955
956 static void clip_main_region_listener(
957         wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar,
958         wmNotifier *wmn, const Scene *UNUSED(scene))
959 {
960         /* context changes */
961         switch (wmn->category) {
962                 case NC_GPENCIL:
963                         if (wmn->action == NA_EDITED)
964                                 ED_region_tag_redraw(ar);
965                         else if (wmn->data & ND_GPENCIL_EDITMODE)
966                                 ED_region_tag_redraw(ar);
967                         break;
968         }
969 }
970
971 /****************** preview region ******************/
972
973 static void clip_preview_region_init(wmWindowManager *wm, ARegion *ar)
974 {
975         wmKeyMap *keymap;
976
977         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
978
979         /* own keymap */
980         keymap = WM_keymap_ensure(wm->defaultconf, "Clip", SPACE_CLIP, 0);
981         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
982
983         keymap = WM_keymap_ensure(wm->defaultconf, "Clip Graph Editor", SPACE_CLIP, 0);
984         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
985
986         keymap = WM_keymap_ensure(wm->defaultconf, "Clip Dopesheet Editor", SPACE_CLIP, 0);
987         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
988 }
989
990 static void graph_region_draw(const bContext *C, ARegion *ar)
991 {
992         View2D *v2d = &ar->v2d;
993         View2DScrollers *scrollers;
994         SpaceClip *sc = CTX_wm_space_clip(C);
995         Scene *scene = CTX_data_scene(C);
996         short unitx, unity;
997         short cfra_flag = 0;
998
999         if (sc->flag & SC_LOCK_TIMECURSOR)
1000                 ED_clip_graph_center_current_frame(scene, ar);
1001
1002         /* clear and setup matrix */
1003         UI_ThemeClearColor(TH_BACK);
1004         GPU_clear(GPU_COLOR_BIT);
1005
1006         UI_view2d_view_ortho(v2d);
1007
1008         /* data... */
1009         clip_draw_graph(sc, ar, scene);
1010
1011         /* current frame indicator line */
1012         if (sc->flag & SC_SHOW_SECONDS) cfra_flag |= DRAWCFRA_UNIT_SECONDS;
1013         ANIM_draw_cfra(C, v2d, cfra_flag);
1014
1015         /* reset view matrix */
1016         UI_view2d_view_restore(C);
1017
1018         /* scrollers */
1019         unitx = (sc->flag & SC_SHOW_SECONDS) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
1020         unity = V2D_UNIT_VALUES;
1021         scrollers = UI_view2d_scrollers_calc(C, v2d, NULL, unitx, V2D_GRID_NOCLAMP, unity, V2D_GRID_NOCLAMP);
1022         UI_view2d_scrollers_draw(C, v2d, scrollers);
1023         UI_view2d_scrollers_free(scrollers);
1024
1025         /* current frame indicator */
1026         if (sc->flag & SC_SHOW_SECONDS) cfra_flag |= DRAWCFRA_UNIT_SECONDS;
1027         UI_view2d_view_orthoSpecial(ar, v2d, 1);
1028         ANIM_draw_cfra_number(C, v2d, cfra_flag);
1029 }
1030
1031 static void dopesheet_region_draw(const bContext *C, ARegion *ar)
1032 {
1033         Scene *scene = CTX_data_scene(C);
1034         SpaceClip *sc = CTX_wm_space_clip(C);
1035         MovieClip *clip = ED_space_clip_get_clip(sc);
1036         View2D *v2d = &ar->v2d;
1037         View2DGrid *grid;
1038         View2DScrollers *scrollers;
1039         short unit = 0, cfra_flag = 0;
1040
1041         if (clip)
1042                 BKE_tracking_dopesheet_update(&clip->tracking);
1043
1044         /* clear and setup matrix */
1045         UI_ThemeClearColor(TH_BACK);
1046         GPU_clear(GPU_COLOR_BIT);
1047
1048         UI_view2d_view_ortho(v2d);
1049
1050         /* time grid */
1051         unit = (sc->flag & SC_SHOW_SECONDS) ? V2D_UNIT_SECONDS : V2D_UNIT_FRAMES;
1052         grid = UI_view2d_grid_calc(scene, v2d, unit, V2D_GRID_CLAMP,
1053                                    V2D_ARG_DUMMY, V2D_ARG_DUMMY, ar->winx, ar->winy);
1054         UI_view2d_grid_draw(v2d, grid, V2D_GRIDLINES_ALL);
1055         UI_view2d_grid_free(grid);
1056
1057         /* data... */
1058         clip_draw_dopesheet_main(sc, ar, scene);
1059
1060         /* current frame indicator line */
1061         if (sc->flag & SC_SHOW_SECONDS) cfra_flag |= DRAWCFRA_UNIT_SECONDS;
1062         ANIM_draw_cfra(C, v2d, cfra_flag);
1063
1064         /* reset view matrix */
1065         UI_view2d_view_restore(C);
1066
1067         /* scrollers */
1068         scrollers = UI_view2d_scrollers_calc(C, v2d, NULL, unit, V2D_GRID_CLAMP, V2D_ARG_DUMMY, V2D_ARG_DUMMY);
1069         UI_view2d_scrollers_draw(C, v2d, scrollers);
1070         UI_view2d_scrollers_free(scrollers);
1071
1072         /* current frame number indicator */
1073         UI_view2d_view_orthoSpecial(ar, v2d, 1);
1074         ANIM_draw_cfra_number(C, v2d, cfra_flag);
1075 }
1076
1077 static void clip_preview_region_draw(const bContext *C, ARegion *ar)
1078 {
1079         SpaceClip *sc = CTX_wm_space_clip(C);
1080
1081         if (sc->view == SC_VIEW_GRAPH)
1082                 graph_region_draw(C, ar);
1083         else if (sc->view == SC_VIEW_DOPESHEET)
1084                 dopesheet_region_draw(C, ar);
1085 }
1086
1087 static void clip_preview_region_listener(
1088         wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *UNUSED(ar),
1089         wmNotifier *UNUSED(wmn), const Scene *UNUSED(scene))
1090 {
1091 }
1092
1093 /****************** channels region ******************/
1094
1095 static void clip_channels_region_init(wmWindowManager *wm, ARegion *ar)
1096 {
1097         wmKeyMap *keymap;
1098
1099         /* ensure the 2d view sync works - main region has bottom scroller */
1100         ar->v2d.scroll = V2D_SCROLL_BOTTOM;
1101
1102         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_LIST, ar->winx, ar->winy);
1103
1104         keymap = WM_keymap_ensure(wm->defaultconf, "Clip Dopesheet Editor", SPACE_CLIP, 0);
1105         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
1106 }
1107
1108 static void clip_channels_region_draw(const bContext *C, ARegion *ar)
1109 {
1110         SpaceClip *sc = CTX_wm_space_clip(C);
1111         MovieClip *clip = ED_space_clip_get_clip(sc);
1112         View2D *v2d = &ar->v2d;
1113
1114         if (clip)
1115                 BKE_tracking_dopesheet_update(&clip->tracking);
1116
1117         /* clear and setup matrix */
1118         UI_ThemeClearColor(TH_BACK);
1119         GPU_clear(GPU_COLOR_BIT);
1120
1121         UI_view2d_view_ortho(v2d);
1122
1123         /* data... */
1124         clip_draw_dopesheet_channels(C, ar);
1125
1126         /* reset view matrix */
1127         UI_view2d_view_restore(C);
1128 }
1129
1130 static void clip_channels_region_listener(
1131         wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *UNUSED(ar),
1132         wmNotifier *UNUSED(wmn), const Scene *UNUSED(scene))
1133 {
1134 }
1135
1136 /****************** header region ******************/
1137
1138 /* add handlers, stuff you only do once or on area/region changes */
1139 static void clip_header_region_init(wmWindowManager *UNUSED(wm), ARegion *ar)
1140 {
1141         ED_region_header_init(ar);
1142 }
1143
1144 static void clip_header_region_draw(const bContext *C, ARegion *ar)
1145 {
1146         ED_region_header(C, ar);
1147 }
1148
1149 static void clip_header_region_listener(
1150         wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar,
1151         wmNotifier *wmn, const Scene *UNUSED(scene))
1152 {
1153         /* context changes */
1154         switch (wmn->category) {
1155                 case NC_SCENE:
1156                         switch (wmn->data) {
1157                                 /* for proportional editmode only */
1158                                 case ND_TOOLSETTINGS:
1159                                         /* TODO - should do this when in mask mode only but no datas available */
1160                                         // if (sc->mode == SC_MODE_MASKEDIT)
1161                                 {
1162                                         ED_region_tag_redraw(ar);
1163                                         break;
1164                                 }
1165                         }
1166                         break;
1167         }
1168 }
1169
1170
1171 /****************** tools region ******************/
1172
1173 /* add handlers, stuff you only do once or on area/region changes */
1174 static void clip_tools_region_init(wmWindowManager *wm, ARegion *ar)
1175 {
1176         wmKeyMap *keymap;
1177
1178         ED_region_panels_init(wm, ar);
1179
1180         keymap = WM_keymap_ensure(wm->defaultconf, "Clip", SPACE_CLIP, 0);
1181         WM_event_add_keymap_handler(&ar->handlers, keymap);
1182 }
1183
1184 static void clip_tools_region_draw(const bContext *C, ARegion *ar)
1185 {
1186         ED_region_panels(C, ar);
1187 }
1188
1189 /****************** tool properties region ******************/
1190
1191 static void clip_props_region_listener(
1192         wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar,
1193         wmNotifier *wmn, const Scene *UNUSED(scene))
1194 {
1195         /* context changes */
1196         switch (wmn->category) {
1197                 case NC_WM:
1198                         if (wmn->data == ND_HISTORY)
1199                                 ED_region_tag_redraw(ar);
1200                         break;
1201                 case NC_SCENE:
1202                         if (wmn->data == ND_MODE)
1203                                 ED_region_tag_redraw(ar);
1204                         break;
1205                 case NC_SPACE:
1206                         if (wmn->data == ND_SPACE_CLIP)
1207                                 ED_region_tag_redraw(ar);
1208                         break;
1209                 case NC_GPENCIL:
1210                         if (wmn->action == NA_EDITED)
1211                                 ED_region_tag_redraw(ar);
1212                         break;
1213         }
1214 }
1215
1216 /****************** properties region ******************/
1217
1218 /* add handlers, stuff you only do once or on area/region changes */
1219 static void clip_properties_region_init(wmWindowManager *wm, ARegion *ar)
1220 {
1221         wmKeyMap *keymap;
1222
1223         ED_region_panels_init(wm, ar);
1224
1225         keymap = WM_keymap_ensure(wm->defaultconf, "Clip", SPACE_CLIP, 0);
1226         WM_event_add_keymap_handler(&ar->handlers, keymap);
1227 }
1228
1229 static void clip_properties_region_draw(const bContext *C, ARegion *ar)
1230 {
1231         SpaceClip *sc = CTX_wm_space_clip(C);
1232
1233         BKE_movieclip_update_scopes(sc->clip, &sc->user, &sc->scopes);
1234
1235         ED_region_panels(C, ar);
1236 }
1237
1238 static void clip_properties_region_listener(
1239         wmWindow *UNUSED(win), ScrArea *UNUSED(sa), ARegion *ar,
1240         wmNotifier *wmn, const Scene *UNUSED(scene))
1241 {
1242         /* context changes */
1243         switch (wmn->category) {
1244                 case NC_GPENCIL:
1245                         if (ELEM(wmn->data, ND_DATA, ND_GPENCIL_EDITMODE))
1246                                 ED_region_tag_redraw(ar);
1247                         break;
1248                 case NC_BRUSH:
1249                         if (wmn->action == NA_EDITED)
1250                                 ED_region_tag_redraw(ar);
1251                         break;
1252         }
1253 }
1254
1255 /********************* registration ********************/
1256
1257 static void clip_id_remap(ScrArea *UNUSED(sa), SpaceLink *slink, ID *old_id, ID *new_id)
1258 {
1259         SpaceClip *sclip = (SpaceClip *)slink;
1260
1261         if (!ELEM(GS(old_id->name), ID_MC, ID_MSK)) {
1262                 return;
1263         }
1264
1265         if ((ID *)sclip->clip == old_id) {
1266                 sclip->clip = (MovieClip *)new_id;
1267                 id_us_ensure_real(new_id);
1268         }
1269
1270         if ((ID *)sclip->mask_info.mask == old_id) {
1271                 sclip->mask_info.mask = (Mask *)new_id;
1272                 id_us_ensure_real(new_id);
1273         }
1274 }
1275
1276 /* only called once, from space/spacetypes.c */
1277 void ED_spacetype_clip(void)
1278 {
1279         SpaceType *st = MEM_callocN(sizeof(SpaceType), "spacetype clip");
1280         ARegionType *art;
1281
1282         st->spaceid = SPACE_CLIP;
1283         strncpy(st->name, "Clip", BKE_ST_MAXNAME);
1284
1285         st->new = clip_new;
1286         st->free = clip_free;
1287         st->init = clip_init;
1288         st->duplicate = clip_duplicate;
1289         st->operatortypes = clip_operatortypes;
1290         st->keymap = clip_keymap;
1291         st->listener = clip_listener;
1292         st->context = clip_context;
1293         st->dropboxes = clip_dropboxes;
1294         st->refresh = clip_refresh;
1295         st->id_remap = clip_id_remap;
1296
1297         /* regions: main window */
1298         art = MEM_callocN(sizeof(ARegionType), "spacetype clip region");
1299         art->regionid = RGN_TYPE_WINDOW;
1300         art->init = clip_main_region_init;
1301         art->draw = clip_main_region_draw;
1302         art->listener = clip_main_region_listener;
1303         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI | ED_KEYMAP_GPENCIL;
1304
1305         BLI_addhead(&st->regiontypes, art);
1306
1307         /* preview */
1308         art = MEM_callocN(sizeof(ARegionType), "spacetype clip region preview");
1309         art->regionid = RGN_TYPE_PREVIEW;
1310         art->prefsizey = 240;
1311         art->init = clip_preview_region_init;
1312         art->draw = clip_preview_region_draw;
1313         art->listener = clip_preview_region_listener;
1314         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI | ED_KEYMAP_VIEW2D;
1315
1316         BLI_addhead(&st->regiontypes, art);
1317
1318         /* regions: properties */
1319         art = MEM_callocN(sizeof(ARegionType), "spacetype clip region properties");
1320         art->regionid = RGN_TYPE_UI;
1321         art->prefsizex = UI_COMPACT_PANEL_WIDTH;
1322         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI;
1323         art->init = clip_properties_region_init;
1324         art->draw = clip_properties_region_draw;
1325         art->listener = clip_properties_region_listener;
1326         BLI_addhead(&st->regiontypes, art);
1327         ED_clip_buttons_register(art);
1328
1329         /* regions: tools */
1330         art = MEM_callocN(sizeof(ARegionType), "spacetype clip region tools");
1331         art->regionid = RGN_TYPE_TOOLS;
1332         art->prefsizex = UI_COMPACT_PANEL_WIDTH;
1333         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI;
1334         art->listener = clip_props_region_listener;
1335         art->init = clip_tools_region_init;
1336         art->draw = clip_tools_region_draw;
1337
1338         BLI_addhead(&st->regiontypes, art);
1339
1340         /* regions: header */
1341         art = MEM_callocN(sizeof(ARegionType), "spacetype clip region");
1342         art->regionid = RGN_TYPE_HEADER;
1343         art->prefsizey = HEADERY;
1344         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI | ED_KEYMAP_VIEW2D | ED_KEYMAP_HEADER;
1345
1346         art->init = clip_header_region_init;
1347         art->draw = clip_header_region_draw;
1348         art->listener = clip_header_region_listener;
1349
1350         BLI_addhead(&st->regiontypes, art);
1351
1352         BKE_spacetype_register(st);
1353
1354         /* channels */
1355         art = MEM_callocN(sizeof(ARegionType), "spacetype clip channels region");
1356         art->regionid = RGN_TYPE_CHANNELS;
1357         art->prefsizex = UI_COMPACT_PANEL_WIDTH;
1358         art->keymapflag = ED_KEYMAP_FRAMES | ED_KEYMAP_UI;
1359         art->listener = clip_channels_region_listener;
1360         art->init = clip_channels_region_init;
1361         art->draw = clip_channels_region_draw;
1362
1363         BLI_addhead(&st->regiontypes, art);
1364
1365         /* regions: hud */
1366         art = ED_area_type_hud(st->spaceid);
1367         BLI_addhead(&st->regiontypes, art);
1368 }