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