doxygen: blender/editors tagged.
[blender.git] / source / blender / editors / space_sequencer / space_sequencer.c
1 /*
2  * $Id$
3  *
4  * ***** BEGIN GPL LICENSE BLOCK *****
5  *
6  * This program is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * as published by the Free Software Foundation; either version 2
9  * of the License, or (at your option) any later version. 
10  *
11  * This program is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software Foundation,
18  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
19  *
20  * The Original Code is Copyright (C) 2008 Blender Foundation.
21  * All rights reserved.
22  *
23  * 
24  * Contributor(s): Blender Foundation
25  *
26  * ***** END GPL LICENSE BLOCK *****
27  */
28
29 /** \file blender/editors/space_sequencer/space_sequencer.c
30  *  \ingroup spseq
31  */
32
33
34 #include <string.h>
35 #include <stdio.h>
36
37 #include "DNA_scene_types.h"
38
39 #include "MEM_guardedalloc.h"
40
41 #include "BLI_blenlib.h"
42 #include "BLI_math.h"
43 #include "BLI_path_util.h"
44 #include "BLI_utildefines.h"
45
46 #include "BKE_context.h"
47 #include "BKE_screen.h"
48 #include "BKE_sequencer.h"
49 #include "BKE_global.h"
50
51 #include "ED_space_api.h"
52 #include "ED_sequencer.h"
53 #include "ED_screen.h"
54 #include "ED_view3d.h" /* only for sequencer view3d drawing callback */
55
56 #include "WM_api.h"
57 #include "WM_types.h"
58
59 #include "UI_resources.h"
60 #include "UI_view2d.h"
61
62 #include "sequencer_intern.h"   // own include
63
64 /* ******************** manage regions ********************* */
65
66 ARegion *sequencer_has_buttons_region(ScrArea *sa)
67 {
68         ARegion *ar, *arnew;
69         
70         for(ar= sa->regionbase.first; ar; ar= ar->next)
71                 if(ar->regiontype==RGN_TYPE_UI)
72                         return ar;
73         
74         /* add subdiv level; after header */
75         for(ar= sa->regionbase.first; ar; ar= ar->next)
76                 if(ar->regiontype==RGN_TYPE_HEADER)
77                         break;
78         
79         /* is error! */
80         if(ar==NULL) return NULL;
81         
82         arnew= MEM_callocN(sizeof(ARegion), "buttons for sequencer");
83         
84         BLI_insertlinkafter(&sa->regionbase, ar, arnew);
85         arnew->regiontype= RGN_TYPE_UI;
86         arnew->alignment= RGN_ALIGN_RIGHT;
87         
88         arnew->flag = RGN_FLAG_HIDDEN;
89         
90         return arnew;
91 }
92
93 static ARegion *sequencer_find_region(ScrArea *sa, short type)
94 {
95         ARegion *ar=NULL;
96         
97         for(ar= sa->regionbase.first; ar; ar= ar->next)
98                 if(ar->regiontype==type)
99                         return ar;
100
101         return ar;
102 }
103
104 void ED_sequencer_update_view(bContext *C, int view)
105 {
106         ScrArea *sa= CTX_wm_area(C);
107         
108         ARegion *ar_main= sequencer_find_region(sa, RGN_TYPE_WINDOW);
109         ARegion *ar_preview= sequencer_find_region(sa, RGN_TYPE_PREVIEW);
110
111         switch (view) {
112                 case SEQ_VIEW_SEQUENCE:
113                         if (ar_main && (ar_main->flag & RGN_FLAG_HIDDEN)) {
114                                 ar_main->flag &= ~RGN_FLAG_HIDDEN;
115                                 ar_main->v2d.flag &= ~V2D_IS_INITIALISED;
116                         }
117                         if (ar_preview && !(ar_preview->flag & RGN_FLAG_HIDDEN)) {
118                                 ar_preview->flag |= RGN_FLAG_HIDDEN;
119                                 ar_preview->v2d.flag &= ~V2D_IS_INITIALISED;
120                                 WM_event_remove_handlers(C, &ar_preview->handlers);
121                         }
122                         if (ar_main) ar_main->alignment= RGN_ALIGN_NONE;
123                         if (ar_preview) ar_preview->alignment= RGN_ALIGN_NONE;
124                         break;
125                 case SEQ_VIEW_PREVIEW:
126                         if (ar_main && !(ar_main->flag & RGN_FLAG_HIDDEN)) {
127                                 ar_main->flag |= RGN_FLAG_HIDDEN;
128                                 ar_main->v2d.flag &= ~V2D_IS_INITIALISED;
129                                 WM_event_remove_handlers(C, &ar_main->handlers);
130                         }
131                         if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) {
132                                 ar_preview->flag &= ~RGN_FLAG_HIDDEN;
133                                 ar_preview->v2d.flag &= ~V2D_IS_INITIALISED;
134                                 ar_preview->v2d.cur = ar_preview->v2d.tot;
135                         }
136                         if (ar_main) ar_main->alignment= RGN_ALIGN_NONE;
137                         if (ar_preview) ar_preview->alignment= RGN_ALIGN_NONE;
138                         break;
139                 case SEQ_VIEW_SEQUENCE_PREVIEW:
140                         if (ar_main && (ar_main->flag & RGN_FLAG_HIDDEN)) {
141                                 ar_main->flag &= ~RGN_FLAG_HIDDEN;
142                                 ar_main->v2d.flag &= ~V2D_IS_INITIALISED;
143                         }
144                         if (ar_preview && (ar_preview->flag & RGN_FLAG_HIDDEN)) {
145                                 ar_preview->flag &= ~RGN_FLAG_HIDDEN;
146                                 ar_preview->v2d.flag &= ~V2D_IS_INITIALISED;
147                                 ar_preview->v2d.cur = ar_preview->v2d.tot;
148                         }
149                         if (ar_main) ar_main->alignment= RGN_ALIGN_NONE;
150                         if (ar_preview) ar_preview->alignment= RGN_ALIGN_TOP;
151                         break;
152         }
153
154         ED_area_initialize(CTX_wm_manager(C), CTX_wm_window(C), sa);
155         ED_area_tag_redraw(sa);
156 }
157
158
159 /* ******************** default callbacks for sequencer space ***************** */
160
161 static SpaceLink *sequencer_new(const bContext *C)
162 {
163         Scene *scene= CTX_data_scene(C);
164         ARegion *ar;
165         SpaceSeq *sseq;
166         
167         sseq= MEM_callocN(sizeof(SpaceSeq), "initsequencer");
168         sseq->spacetype= SPACE_SEQ;
169         sseq->zoom= 4;
170         sseq->chanshown = 0;
171         sseq->view = SEQ_VIEW_SEQUENCE;
172         sseq->mainb = SEQ_DRAW_IMG_IMBUF;
173         /* header */
174         ar= MEM_callocN(sizeof(ARegion), "header for sequencer");
175         
176         BLI_addtail(&sseq->regionbase, ar);
177         ar->regiontype= RGN_TYPE_HEADER;
178         ar->alignment= RGN_ALIGN_BOTTOM;
179         
180         /* buttons/list view */
181         ar= MEM_callocN(sizeof(ARegion), "buttons for sequencer");
182         
183         BLI_addtail(&sseq->regionbase, ar);
184         ar->regiontype= RGN_TYPE_UI;
185         ar->alignment= RGN_ALIGN_RIGHT;
186         ar->flag = RGN_FLAG_HIDDEN;
187         
188         /* preview area */
189         /* NOTE: if you change values here, also change them in sequencer_init_preview_region */
190         ar= MEM_callocN(sizeof(ARegion), "preview area for sequencer");
191         BLI_addtail(&sseq->regionbase, ar);
192         ar->regiontype= RGN_TYPE_PREVIEW;
193         ar->alignment= RGN_ALIGN_TOP;
194         ar->flag |= RGN_FLAG_HIDDEN;
195         /* for now, aspect ratio should be maintained, and zoom is clamped within sane default limits */
196         ar->v2d.keepzoom= V2D_KEEPASPECT | V2D_KEEPZOOM;
197         ar->v2d.minzoom= 0.00001f;
198         ar->v2d.maxzoom= 100000.0f;
199         ar->v2d.tot.xmin= -960.0f; /* 1920 width centered */
200         ar->v2d.tot.ymin= -540.0f; /* 1080 height centered */
201         ar->v2d.tot.xmax= 960.0f;
202         ar->v2d.tot.ymax= 540.0f;
203         ar->v2d.min[0]= 0.0f;
204         ar->v2d.min[1]= 0.0f;
205         ar->v2d.max[0]= 12000.0f;
206         ar->v2d.max[1]= 12000.0f;
207         ar->v2d.cur= ar->v2d.tot;
208         ar->v2d.align= V2D_ALIGN_FREE; 
209         ar->v2d.keeptot= V2D_KEEPTOT_FREE;
210
211
212         /* main area */
213         ar= MEM_callocN(sizeof(ARegion), "main area for sequencer");
214         
215         BLI_addtail(&sseq->regionbase, ar);
216         ar->regiontype= RGN_TYPE_WINDOW;
217         
218         
219         /* seq space goes from (0,8) to (0, efra) */
220         
221         ar->v2d.tot.xmin= 0.0f;
222         ar->v2d.tot.ymin= 0.0f;
223         ar->v2d.tot.xmax= scene->r.efra;
224         ar->v2d.tot.ymax= 8.0f;
225         
226         ar->v2d.cur= ar->v2d.tot;
227         
228         ar->v2d.min[0]= 10.0f;
229         ar->v2d.min[1]= 4.0f;
230         
231         ar->v2d.max[0]= MAXFRAMEF;
232         ar->v2d.max[1]= MAXSEQ;
233         
234         ar->v2d.minzoom= 0.01f;
235         ar->v2d.maxzoom= 100.0f;
236         
237         ar->v2d.scroll |= (V2D_SCROLL_BOTTOM|V2D_SCROLL_SCALE_HORIZONTAL);
238         ar->v2d.scroll |= (V2D_SCROLL_LEFT|V2D_SCROLL_SCALE_VERTICAL);
239         ar->v2d.keepzoom= 0;
240         ar->v2d.keeptot= 0;
241         ar->v2d.align= V2D_ALIGN_NO_NEG_Y;
242
243         return (SpaceLink *)sseq;
244 }
245
246 /* not spacelink itself */
247 static void sequencer_free(SpaceLink *UNUSED(sl))
248 {       
249 //      SpaceSeq *sseq= (SpaceSequencer*) sl;
250         
251 // XXX  if(sseq->gpd) free_gpencil_data(sseq->gpd);
252
253 }
254
255
256 /* spacetype; init callback */
257 static void sequencer_init(struct wmWindowManager *UNUSED(wm), ScrArea *UNUSED(sa))
258 {
259         
260 }
261
262 static SpaceLink *sequencer_duplicate(SpaceLink *sl)
263 {
264         SpaceSeq *sseqn= MEM_dupallocN(sl);
265         
266         /* clear or remove stuff from old */
267 // XXX  sseq->gpd= gpencil_data_duplicate(sseq->gpd);
268
269         return (SpaceLink *)sseqn;
270 }
271
272
273
274 /* *********************** sequencer (main) region ************************ */
275 /* add handlers, stuff you only do once or on area/region changes */
276 static void sequencer_main_area_init(wmWindowManager *wm, ARegion *ar)
277 {
278         wmKeyMap *keymap;
279         ListBase *lb;
280         
281         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
282         
283         keymap= WM_keymap_find(wm->defaultconf, "SequencerCommon", SPACE_SEQ, 0);
284         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
285         
286         /* own keymap */
287         keymap= WM_keymap_find(wm->defaultconf, "Sequencer", SPACE_SEQ, 0);
288         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
289         
290         /* add drop boxes */
291         lb= WM_dropboxmap_find("Sequencer", SPACE_SEQ, RGN_TYPE_WINDOW);
292         
293         WM_event_add_dropbox_handler(&ar->handlers, lb);
294         
295 }
296
297 static void sequencer_main_area_draw(const bContext *C, ARegion *ar)
298 {
299 //      ScrArea *sa= CTX_wm_area(C);
300         
301         /* NLE - strip editing timeline interface */
302         draw_timeline_seq(C, ar);
303 }
304
305 /* ************* dropboxes ************* */
306
307 static int image_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
308 {
309         if(drag->type==WM_DRAG_PATH)
310                 if(ELEM(drag->icon, ICON_FILE_IMAGE, ICON_FILE_BLANK))  /* rule might not work? */
311                         return 1;
312         return 0;
313 }
314
315 static int movie_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
316 {
317         if(drag->type==WM_DRAG_PATH)
318                 if(ELEM3(drag->icon, 0, ICON_FILE_MOVIE, ICON_FILE_BLANK))      /* rule might not work? */
319                         return 1;
320         return 0;
321 }
322
323 static int sound_drop_poll(bContext *UNUSED(C), wmDrag *drag, wmEvent *UNUSED(event))
324 {
325         if(drag->type==WM_DRAG_PATH)
326                 if(ELEM(drag->icon, ICON_FILE_SOUND, ICON_FILE_BLANK))  /* rule might not work? */
327                         return 1;
328         return 0;
329 }
330
331 static void sequencer_drop_copy(wmDrag *drag, wmDropBox *drop)
332 {
333         /* copy drag path to properties */
334         if(RNA_struct_find_property(drop->ptr, "filepath"))
335                 RNA_string_set(drop->ptr, "filepath", drag->path);
336
337         if(RNA_struct_find_property(drop->ptr, "directory")) {
338                 PointerRNA itemptr;
339                 char dir[FILE_MAX], file[FILE_MAX];
340
341                 BLI_split_dirfile(drag->path, dir, file);
342                 
343                 RNA_string_set(drop->ptr, "directory", dir);
344
345                 RNA_collection_clear(drop->ptr, "files");
346                 RNA_collection_add(drop->ptr, "files", &itemptr);
347                 RNA_string_set(&itemptr, "name", file);
348         }
349 }
350
351 /* this region dropbox definition */
352 static void sequencer_dropboxes(void)
353 {
354         ListBase *lb= WM_dropboxmap_find("Sequencer", SPACE_SEQ, RGN_TYPE_WINDOW);
355         
356         WM_dropbox_add(lb, "SEQUENCER_OT_image_strip_add", image_drop_poll, sequencer_drop_copy);
357         WM_dropbox_add(lb, "SEQUENCER_OT_movie_strip_add", movie_drop_poll, sequencer_drop_copy);
358         WM_dropbox_add(lb, "SEQUENCER_OT_sound_strip_add", sound_drop_poll, sequencer_drop_copy);
359 }
360
361 /* ************* end drop *********** */
362
363 /* add handlers, stuff you only do once or on area/region changes */
364 static void sequencer_header_area_init(wmWindowManager *UNUSED(wm), ARegion *ar)
365 {
366         ED_region_header_init(ar);
367 }
368
369 static void sequencer_header_area_draw(const bContext *C, ARegion *ar)
370 {
371         ED_region_header(C, ar);
372 }
373
374 static void sequencer_main_area_listener(ARegion *ar, wmNotifier *wmn)
375 {
376         /* context changes */
377         switch(wmn->category) {
378                 case NC_SCENE:
379                         switch(wmn->data) {
380                                 case ND_FRAME:
381                                 case ND_FRAME_RANGE:
382                                 case ND_MARKERS:
383                                 case ND_RENDER_OPTIONS: /* for FPS and FPS Base */
384                                 case ND_SEQUENCER:
385                                         ED_region_tag_redraw(ar);
386                                         break;
387                         }
388                         break;
389                 case NC_SPACE:
390                         if(wmn->data == ND_SPACE_SEQUENCER)
391                                 ED_region_tag_redraw(ar);
392                         break;
393                 case NC_ID:
394                         if(wmn->action == NA_RENAME)
395                                 ED_region_tag_redraw(ar);
396                         break;
397         }
398 }
399
400 /* *********************** preview region ************************ */
401 static void sequencer_preview_area_init(wmWindowManager *wm, ARegion *ar)
402 {
403         wmKeyMap *keymap;
404
405         UI_view2d_region_reinit(&ar->v2d, V2D_COMMONVIEW_CUSTOM, ar->winx, ar->winy);
406         
407         keymap= WM_keymap_find(wm->defaultconf, "SequencerCommon", SPACE_SEQ, 0);
408         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
409
410         /* own keymap */
411         keymap= WM_keymap_find(wm->defaultconf, "SequencerPreview", SPACE_SEQ, 0);
412         WM_event_add_keymap_handler_bb(&ar->handlers, keymap, &ar->v2d.mask, &ar->winrct);
413 }
414
415 static void sequencer_preview_area_draw(const bContext *C, ARegion *ar)
416 {
417         ScrArea *sa= CTX_wm_area(C);
418         SpaceSeq *sseq= sa->spacedata.first;
419         Scene *scene= CTX_data_scene(C);
420         
421         /* XXX temp fix for wrong setting in sseq->mainb */
422         if (sseq->mainb == SEQ_DRAW_SEQUENCE) sseq->mainb = SEQ_DRAW_IMG_IMBUF;
423
424         draw_image_seq(C, scene, ar, sseq, scene->r.cfra, 0);
425
426         if(scene->ed && scene->ed->over_flag & SEQ_EDIT_OVERLAY_SHOW && sseq->mainb == SEQ_DRAW_IMG_IMBUF) {
427                 int over_cfra;
428
429                 if(scene->ed->over_flag & SEQ_EDIT_OVERLAY_ABS)
430                         over_cfra= scene->ed->over_cfra;
431                 else
432                         over_cfra= scene->r.cfra + scene->ed->over_ofs;
433
434                 if(over_cfra != scene->r.cfra)
435                         draw_image_seq(C, scene, ar, sseq, scene->r.cfra, over_cfra - scene->r.cfra);
436         }
437
438 }
439
440 static void sequencer_preview_area_listener(ARegion *ar, wmNotifier *wmn)
441 {
442         /* context changes */
443         switch(wmn->category) {
444                 case NC_SCENE:
445                         switch(wmn->data) {
446                                 case ND_FRAME:
447                                 case ND_MARKERS:
448                                 case ND_SEQUENCER:
449                                         ED_region_tag_redraw(ar);
450                                         break;
451                         }
452                         break;
453                 case NC_SPACE:
454                         if(wmn->data == ND_SPACE_SEQUENCER)
455                                 ED_region_tag_redraw(ar);
456                         break;
457                 case NC_ID:
458                         switch(wmn->data) {
459                                 case NA_RENAME:
460                                         ED_region_tag_redraw(ar);
461                                         break;
462                         }
463                         break;
464         }
465 }
466
467 /* *********************** buttons region ************************ */
468
469 /* add handlers, stuff you only do once or on area/region changes */
470 static void sequencer_buttons_area_init(wmWindowManager *wm, ARegion *ar)
471 {
472         
473         ED_region_panels_init(wm, ar);
474         
475 }
476
477 static void sequencer_buttons_area_draw(const bContext *C, ARegion *ar)
478 {
479         ED_region_panels(C, ar, 1, NULL, -1);
480 }
481
482 static void sequencer_buttons_area_listener(ARegion *ar, wmNotifier *wmn)
483 {
484         /* context changes */
485         switch(wmn->category) {
486                 case NC_SCENE:
487                 switch(wmn->data) {
488                         case ND_FRAME:
489                         case ND_SEQUENCER:
490                                 ED_region_tag_redraw(ar);
491                                 break;
492                 }
493                 break;
494                 case NC_SPACE:
495                         if(wmn->data == ND_SPACE_SEQUENCER)
496                                 ED_region_tag_redraw(ar);
497                         break;
498                 case NC_ID:
499                         if(wmn->action == NA_RENAME)
500                                 ED_region_tag_redraw(ar);
501                         break;
502         }
503 }
504 /* ************************************* */
505
506 /* only called once, from space/spacetypes.c */
507 void ED_spacetype_sequencer(void)
508 {
509         SpaceType *st= MEM_callocN(sizeof(SpaceType), "spacetype sequencer");
510         ARegionType *art;
511         
512         st->spaceid= SPACE_SEQ;
513         strncpy(st->name, "Sequencer", BKE_ST_MAXNAME);
514         
515         st->new= sequencer_new;
516         st->free= sequencer_free;
517         st->init= sequencer_init;
518         st->duplicate= sequencer_duplicate;
519         st->operatortypes= sequencer_operatortypes;
520         st->keymap= sequencer_keymap;
521         st->dropboxes= sequencer_dropboxes;
522
523         /* regions: main window */
524         art= MEM_callocN(sizeof(ARegionType), "spacetype sequencer region");
525         art->regionid = RGN_TYPE_WINDOW;
526         art->init= sequencer_main_area_init;
527         art->draw= sequencer_main_area_draw;
528         art->listener= sequencer_main_area_listener;
529         art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_MARKERS|ED_KEYMAP_FRAMES|ED_KEYMAP_ANIMATION;
530
531         BLI_addhead(&st->regiontypes, art);
532
533         /* preview */
534         art= MEM_callocN(sizeof(ARegionType), "spacetype sequencer region");
535         art->regionid = RGN_TYPE_PREVIEW;
536         art->prefsizey = 240; // XXX
537         art->init= sequencer_preview_area_init;
538         art->draw= sequencer_preview_area_draw;
539         art->listener= sequencer_preview_area_listener;
540         art->keymapflag= ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_ANIMATION;
541         BLI_addhead(&st->regiontypes, art);
542         
543         /* regions: listview/buttons */
544         art= MEM_callocN(sizeof(ARegionType), "spacetype sequencer region");
545         art->regionid = RGN_TYPE_UI;
546         art->prefsizex= 220; // XXX
547         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_FRAMES;
548         art->listener= sequencer_buttons_area_listener;
549         art->init= sequencer_buttons_area_init;
550         art->draw= sequencer_buttons_area_draw;
551         BLI_addhead(&st->regiontypes, art);
552         
553         /* Keep as python only for now
554         sequencer_buttons_register(art);
555         */
556
557         /* regions: header */
558         art= MEM_callocN(sizeof(ARegionType), "spacetype sequencer region");
559         art->regionid = RGN_TYPE_HEADER;
560         art->prefsizey= HEADERY;
561         art->keymapflag= ED_KEYMAP_UI|ED_KEYMAP_VIEW2D|ED_KEYMAP_FRAMES|ED_KEYMAP_HEADER;
562         
563         art->init= sequencer_header_area_init;
564         art->draw= sequencer_header_area_draw;
565         art->listener= sequencer_main_area_listener;
566         
567         BLI_addhead(&st->regiontypes, art);
568         
569         BKE_spacetype_register(st);
570
571         /* set the sequencer callback when not in background mode */
572         if(G.background==0) {
573                 sequencer_view3d_cb= ED_view3d_draw_offscreen_imbuf_simple;
574         }
575 }
576