Camera tracking integration
[blender.git] / release / scripts / startup / bl_ui / space_sequencer.py
1 # ##### BEGIN GPL LICENSE BLOCK #####
2 #
3 #  This program is free software; you can redistribute it and/or
4 #  modify it under the terms of the GNU General Public License
5 #  as published by the Free Software Foundation; either version 2
6 #  of the License, or (at your option) any later version.
7 #
8 #  This program is distributed in the hope that it will be useful,
9 #  but WITHOUT ANY WARRANTY; without even the implied warranty of
10 #  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11 #  GNU General Public License for more details.
12 #
13 #  You should have received a copy of the GNU General Public License
14 #  along with this program; if not, write to the Free Software Foundation,
15 #  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21
22
23 def act_strip(context):
24     try:
25         return context.scene.sequence_editor.active_strip
26     except AttributeError:
27         return None
28
29
30 class SEQUENCER_HT_header(bpy.types.Header):
31     bl_space_type = 'SEQUENCE_EDITOR'
32
33     def draw(self, context):
34         layout = self.layout
35
36         st = context.space_data
37
38         row = layout.row(align=True)
39         row.template_header()
40
41         if context.area.show_menus:
42             sub = row.row(align=True)
43             sub.menu("SEQUENCER_MT_view")
44
45             if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
46                 sub.menu("SEQUENCER_MT_select")
47                 sub.menu("SEQUENCER_MT_marker")
48                 sub.menu("SEQUENCER_MT_add")
49                 sub.menu("SEQUENCER_MT_strip")
50
51         layout.prop(st, "view_type", expand=True, text="")
52
53         if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
54             layout.prop(st, "display_mode", expand=True, text="")
55
56         if st.view_type == 'SEQUENCER':
57             row = layout.row(align=True)
58             row.operator("sequencer.copy", text="", icon='COPYDOWN')
59             row.operator("sequencer.paste", text="", icon='PASTEDOWN')
60
61             layout.separator()
62             layout.operator("sequencer.refresh_all")
63             layout.template_running_jobs()
64         elif st.view_type == 'SEQUENCER_PREVIEW':
65             layout.separator()
66             layout.operator("sequencer.refresh_all")
67             layout.prop(st, "display_channel", text="Channel")
68         else:
69             layout.prop(st, "display_channel", text="Channel")
70
71             ed = context.scene.sequence_editor
72             if ed:
73                 row = layout.row(align=True)
74                 row.prop(ed, "show_overlay", text="", icon='GHOST_ENABLED')
75                 if ed.show_overlay:
76                     row.prop(ed, "overlay_frame", text="")
77                     row.prop(ed, "overlay_lock", text="", icon='LOCKED')
78
79
80 class SEQUENCER_MT_view_toggle(bpy.types.Menu):
81     bl_label = "View Type"
82
83     def draw(self, context):
84         layout = self.layout
85
86         layout.operator("sequencer.view_toggle").type = 'SEQUENCER'
87         layout.operator("sequencer.view_toggle").type = 'PREVIEW'
88         layout.operator("sequencer.view_toggle").type = 'SEQUENCER_PREVIEW'
89
90
91 class SEQUENCER_MT_view(bpy.types.Menu):
92     bl_label = "View"
93
94     def draw(self, context):
95         layout = self.layout
96
97         st = context.space_data
98
99         layout.column()
100
101         layout.operator("sequencer.properties", icon='MENU_PANEL')
102
103         layout.separator()
104
105         if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
106             layout.operator("sequencer.view_all", text='View all Sequences')
107         if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
108             layout.operator_context = 'INVOKE_REGION_PREVIEW'
109             layout.operator("sequencer.view_all_preview", text='Fit preview in window')
110             layout.operator("sequencer.view_zoom_ratio", text='Show preview 1:1').ratio = 1.0
111             layout.operator_context = 'INVOKE_DEFAULT'
112
113             # # XXX, invokes in the header view
114             # layout.operator("sequencer.view_ghost_border", text='Overlay Border')
115
116         layout.operator("sequencer.view_selected")
117
118         layout.prop(st, "show_frames")
119         layout.prop(st, "show_frame_indicator")
120         if st.display_mode == 'IMAGE':
121             layout.prop(st, "show_safe_margin")
122         if st.display_mode == 'WAVEFORM':
123             layout.prop(st, "show_separate_color")
124
125         layout.separator()
126         layout.prop(st, "use_marker_sync")
127         layout.separator()
128
129         layout.operator("screen.area_dupli")
130         layout.operator("screen.screen_full_area")
131
132
133 class SEQUENCER_MT_select(bpy.types.Menu):
134     bl_label = "Select"
135
136     def draw(self, context):
137         layout = self.layout
138
139         layout.column()
140         layout.operator("sequencer.select_active_side", text="Strips to the Left").side = 'LEFT'
141         layout.operator("sequencer.select_active_side", text="Strips to the Right").side = 'RIGHT'
142         layout.separator()
143         layout.operator("sequencer.select_handles", text="Surrounding Handles").side = 'BOTH'
144         layout.operator("sequencer.select_handles", text="Left Handle").side = 'LEFT'
145         layout.operator("sequencer.select_handles", text="Right Handle").side = 'RIGHT'
146         layout.separator()
147         layout.operator("sequencer.select_linked")
148         layout.operator("sequencer.select_all_toggle")
149         layout.operator("sequencer.select_inverse")
150
151
152 class SEQUENCER_MT_marker(bpy.types.Menu):
153     bl_label = "Marker"
154
155     def draw(self, context):
156         layout = self.layout
157
158         #layout.operator_context = 'EXEC_REGION_WIN'
159
160         layout.column()
161         layout.operator("marker.add", "Add Marker")
162         layout.operator("marker.duplicate", text="Duplicate Marker")
163         layout.operator("marker.delete", text="Delete Marker")
164
165         layout.separator()
166
167         layout.operator("marker.rename", text="Rename Marker")
168         layout.operator("marker.move", text="Grab/Move Marker")
169
170         #layout.operator("sequencer.sound_strip_add", text="Transform Markers") # toggle, will be rna - (sseq->flag & SEQ_MARKER_TRANS)
171
172
173 class SEQUENCER_MT_add(bpy.types.Menu):
174     bl_label = "Add"
175
176     def draw(self, context):
177         layout = self.layout
178         layout.operator_context = 'INVOKE_REGION_WIN'
179
180         layout.column()
181         if len(bpy.data.scenes) > 10:
182             layout.operator_context = 'INVOKE_DEFAULT'
183             layout.operator("sequencer.scene_strip_add", text="Scene...")
184         else:
185             layout.operator_menu_enum("sequencer.scene_strip_add", "scene", text="Scene...")
186
187         layout.operator("sequencer.movie_strip_add", text="Movie")
188         layout.operator("sequencer.image_strip_add", text="Image")
189         layout.operator("sequencer.sound_strip_add", text="Sound")
190
191         layout.menu("SEQUENCER_MT_add_effect")
192
193
194 class SEQUENCER_MT_add_effect(bpy.types.Menu):
195     bl_label = "Effect Strip..."
196
197     def draw(self, context):
198         layout = self.layout
199         layout.operator_context = 'INVOKE_REGION_WIN'
200
201         layout.column()
202         layout.operator("sequencer.effect_strip_add", text="Add").type = 'ADD'
203         layout.operator("sequencer.effect_strip_add", text="Subtract").type = 'SUBTRACT'
204         layout.operator("sequencer.effect_strip_add", text="Alpha Over").type = 'ALPHA_OVER'
205         layout.operator("sequencer.effect_strip_add", text="Alpha Under").type = 'ALPHA_UNDER'
206         layout.operator("sequencer.effect_strip_add", text="Cross").type = 'CROSS'
207         layout.operator("sequencer.effect_strip_add", text="Gamma Cross").type = 'GAMMA_CROSS'
208         layout.operator("sequencer.effect_strip_add", text="Multiply").type = 'MULTIPLY'
209         layout.operator("sequencer.effect_strip_add", text="Over Drop").type = 'OVER_DROP'
210         layout.operator("sequencer.effect_strip_add", text="Plugin").type = 'PLUGIN'
211         layout.operator("sequencer.effect_strip_add", text="Wipe").type = 'WIPE'
212         layout.operator("sequencer.effect_strip_add", text="Glow").type = 'GLOW'
213         layout.operator("sequencer.effect_strip_add", text="Transform").type = 'TRANSFORM'
214         layout.operator("sequencer.effect_strip_add", text="Color").type = 'COLOR'
215         layout.operator("sequencer.effect_strip_add", text="Speed Control").type = 'SPEED'
216         layout.operator("sequencer.effect_strip_add", text="Multicam Selector").type = 'MULTICAM'
217         layout.operator("sequencer.effect_strip_add", text="Adjustment Layer").type = 'ADJUSTMENT'
218
219
220 class SEQUENCER_MT_strip(bpy.types.Menu):
221     bl_label = "Strip"
222
223     def draw(self, context):
224         layout = self.layout
225
226         layout.operator_context = 'INVOKE_REGION_WIN'
227
228         layout.column()
229         layout.operator("transform.transform", text="Grab/Move").mode = 'TRANSLATION'
230         layout.operator("transform.transform", text="Grab/Extend from frame").mode = 'TIME_EXTEND'
231         #  uiItemO(layout, NULL, 0, "sequencer.strip_snap"); // TODO - add this operator
232         layout.separator()
233
234         layout.operator("sequencer.cut", text="Cut (hard) at frame").type = 'HARD'
235         layout.operator("sequencer.cut", text="Cut (soft) at frame").type = 'SOFT'
236         layout.operator("sequencer.images_separate")
237         layout.operator("sequencer.deinterlace_selected_movies")
238         layout.operator("sequencer.rebuild_proxy")
239         layout.separator()
240
241         layout.operator("sequencer.duplicate")
242         layout.operator("sequencer.delete")
243
244         strip = act_strip(context)
245
246         if strip:
247             stype = strip.type
248
249             # XXX note strip.type is never equal to 'EFFECT', look at seq_type_items within rna_sequencer.c
250             if stype == 'EFFECT':
251                 pass
252                 # layout.separator()
253                 # layout.operator("sequencer.effect_change")
254                 # layout.operator("sequencer.effect_reassign_inputs")
255             elif stype == 'IMAGE':
256                 layout.separator()
257                 # layout.operator("sequencer.image_change")
258                 layout.operator("sequencer.rendersize")
259             elif stype == 'SCENE':
260                 pass
261                 # layout.separator()
262                 # layout.operator("sequencer.scene_change", text="Change Scene")
263             elif stype == 'MOVIE':
264                 layout.separator()
265                 # layout.operator("sequencer.movie_change")
266                 layout.operator("sequencer.rendersize")
267
268         layout.separator()
269
270         layout.operator("sequencer.meta_make")
271         layout.operator("sequencer.meta_separate")
272
273         #if (ed && (ed->metastack.first || (ed->act_seq && ed->act_seq->type == SEQ_META))) {
274         #       uiItemS(layout);
275         #       uiItemO(layout, NULL, 0, "sequencer.meta_toggle");
276         #}
277
278         layout.separator()
279         layout.operator("sequencer.reload")
280         layout.operator("sequencer.reassign_inputs")
281         layout.operator("sequencer.swap_inputs")
282         layout.separator()
283         layout.operator("sequencer.lock")
284         layout.operator("sequencer.unlock")
285         layout.operator("sequencer.mute")
286         layout.operator("sequencer.unmute")
287
288         layout.operator("sequencer.mute", text="Mute Deselected Strips").unselected = True
289
290         layout.operator("sequencer.snap")
291
292         layout.operator_menu_enum("sequencer.swap", "side")
293
294         layout.separator()
295
296         layout.operator("sequencer.swap_data")
297
298
299 class SequencerButtonsPanel():
300     bl_space_type = 'SEQUENCE_EDITOR'
301     bl_region_type = 'UI'
302
303     @staticmethod
304     def has_sequencer(context):
305         return (context.space_data.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'})
306
307     @classmethod
308     def poll(cls, context):
309         return cls.has_sequencer(context) and (act_strip(context) is not None)
310
311
312 class SequencerButtonsPanel_Output():
313     bl_space_type = 'SEQUENCE_EDITOR'
314     bl_region_type = 'UI'
315
316     @staticmethod
317     def has_preview(context):
318         return (context.space_data.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'})
319
320     @classmethod
321     def poll(cls, context):
322         return cls.has_preview(context)
323
324
325 class SEQUENCER_PT_edit(SequencerButtonsPanel, bpy.types.Panel):
326     bl_label = "Edit Strip"
327
328     def draw(self, context):
329         layout = self.layout
330         scene = context.scene
331         frame_current = scene.frame_current
332         strip = act_strip(context)
333
334         split = layout.split(percentage=0.3)
335         split.label(text="Name:")
336         split.prop(strip, "name", text="")
337
338         split = layout.split(percentage=0.3)
339         split.label(text="Type:")
340         split.prop(strip, "type", text="")
341
342         split = layout.split(percentage=0.3)
343         split.label(text="Blend:")
344         split.prop(strip, "blend_type", text="")
345
346         row = layout.row(align=True)
347         sub = row.row()
348         sub.active = (not strip.mute)
349         sub.prop(strip, "blend_alpha", text="Opacity", slider=True)
350         row.prop(strip, "mute", toggle=True, icon='RESTRICT_VIEW_ON' if strip.mute else 'RESTRICT_VIEW_OFF', text="")
351         row.prop(strip, "lock", toggle=True, icon='LOCKED' if strip.lock else 'UNLOCKED', text="")
352
353         col = layout.column()
354         sub = col.column()
355         sub.enabled = not strip.lock
356         sub.prop(strip, "channel")
357         sub.prop(strip, "frame_start")
358         sub.prop(strip, "frame_final_duration")
359
360         col = layout.column(align=True)
361         row = col.row()
362         row.label(text="Final Length: %s" % bpy.utils.smpte_from_frame(strip.frame_final_duration))
363         row = col.row()
364         row.active = (frame_current >= strip.frame_start and frame_current <= strip.frame_start + strip.frame_duration)
365         row.label(text="Playhead: %d" % (frame_current - strip.frame_start))
366
367         col.label(text="Frame Offset %d:%d" % (strip.frame_offset_start, strip.frame_offset_end))
368         col.label(text="Frame Still %d:%d" % (strip.frame_still_start, strip.frame_still_end))
369
370         elem = False
371
372         if strip.type == 'IMAGE':
373             elem = strip.getStripElem(frame_current)
374         elif strip.type == 'MOVIE':
375             elem = strip.elements[0]
376
377         if elem and elem.orig_width > 0 and elem.orig_height > 0:
378             col.label(text="Orig Dim: %dx%d" % (elem.orig_width, elem.orig_height))
379
380
381 class SEQUENCER_PT_effect(SequencerButtonsPanel, bpy.types.Panel):
382     bl_label = "Effect Strip"
383
384     @classmethod
385     def poll(cls, context):
386         if not cls.has_sequencer(context):
387             return False
388
389         strip = act_strip(context)
390         if not strip:
391             return False
392
393         return strip.type in {'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
394                               'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
395                               'PLUGIN',
396                               'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', 'SPEED',
397                               'MULTICAM', 'ADJUSTMENT'}
398
399     def draw(self, context):
400         layout = self.layout
401
402         strip = act_strip(context)
403         if strip.input_count > 0:
404             col = layout.column()
405             col.prop(strip, "input_1")
406             if strip.input_count > 1:
407                 col.prop(strip, "input_2")
408             if strip.input_count > 2:
409                 col.prop(strip, "input_3")
410
411         if strip.type == 'COLOR':
412             layout.prop(strip, "color")
413
414         elif strip.type == 'WIPE':
415
416             col = layout.column()
417             col.prop(strip, "transition_type")
418             col.label(text="Direction:")
419             col.row().prop(strip, "direction", expand=True)
420
421             col = layout.column()
422             col.prop(strip, "blur_width", slider=True)
423             if strip.transition_type in {'SINGLE', 'DOUBLE'}:
424                 col.prop(strip, "angle")
425
426         elif strip.type == 'GLOW':
427             flow = layout.column_flow()
428             flow.prop(strip, "threshold", slider=True)
429             flow.prop(strip, "clamp", slider=True)
430             flow.prop(strip, "boost_factor")
431             flow.prop(strip, "blur_radius")
432
433             row = layout.row()
434             row.prop(strip, "quality", slider=True)
435             row.prop(strip, "use_only_boost")
436
437         elif strip.type == 'SPEED':
438             layout.prop(strip, "use_default_fade", "Stretch to input strip length")
439             if not strip.use_default_fade:
440                 layout.prop(strip, "use_as_speed")
441                 if strip.use_as_speed:
442                     layout.prop(strip, "speed_factor")
443                 else:
444                     layout.prop(strip, "speed_factor", text="Frame number")
445                     layout.prop(strip, "scale_to_length")
446
447             #doesn't work currently
448             #layout.prop(strip, "use_frame_blend")
449
450         elif strip.type == 'TRANSFORM':
451             self.draw_panel_transform(strip)
452
453         elif strip.type == "MULTICAM":
454             layout.prop(strip, "multicam_source")
455
456             row = layout.row(align=True)
457             sub = row.row()
458             sub.scale_x = 2.0
459
460             sub.operator("screen.animation_play", text="", icon='PAUSE' if context.screen.is_animation_playing else 'PLAY')
461
462             row.label("Cut To")
463             for i in range(1, strip.channel):
464                 row.operator("sequencer.cut_multicam", text=str(i)).camera = i
465
466         col = layout.column(align=True)
467         if strip.type == 'SPEED':
468             col.prop(strip, "multiply_speed")
469         elif strip.type in {'CROSS', 'GAMMA_CROSS', 'PLUGIN', 'WIPE'}:
470                 col.prop(strip, "use_default_fade", "Default fade")
471                 if not strip.use_default_fade:
472                     col.prop(strip, "effect_fader", text="Effect fader")
473
474         layout.prop(strip, "use_translation", text="Image Offset:")
475         if strip.use_translation:
476             col = layout.column(align=True)
477             col.prop(strip.transform, "offset_x", text="X")
478             col.prop(strip.transform, "offset_y", text="Y")
479
480         layout.prop(strip, "use_crop", text="Image Crop:")
481         if strip.use_crop:
482             col = layout.column(align=True)
483             col.prop(strip.crop, "max_y")
484             col.prop(strip.crop, "min_x")
485             col.prop(strip.crop, "min_y")
486             col.prop(strip.crop, "max_x")
487
488     def draw_panel_transform(self, strip):
489         layout = self.layout
490         col = layout.column()
491
492         col.prop(strip, "interpolation")
493         col.prop(strip, "translation_unit")
494         col = layout.column(align=True)
495         col.label(text="Position:")
496         col.prop(strip, "translate_start_x", text="X")
497         col.prop(strip, "translate_start_y", text="Y")
498
499         layout.separator()
500
501         col = layout.column(align=True)
502         col.prop(strip, "use_uniform_scale")
503         if (strip.use_uniform_scale):
504             col = layout.column(align=True)
505             col.prop(strip, "scale_start_x", text="Scale")
506         else:
507             col = layout.column(align=True)
508             col.label(text="Scale:")
509             col.prop(strip, "scale_start_x", text="X")
510             col.prop(strip, "scale_start_y", text="Y")
511
512         layout.separator()
513
514         col = layout.column(align=True)
515         col.label(text="Rotation:")
516         col.prop(strip, "rotation_start", text="Rotation")
517
518
519 class SEQUENCER_PT_input(SequencerButtonsPanel, bpy.types.Panel):
520     bl_label = "Strip Input"
521
522     @classmethod
523     def poll(cls, context):
524         if not cls.has_sequencer(context):
525             return False
526
527         strip = act_strip(context)
528         if not strip:
529             return False
530
531         return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'META',
532                               'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
533                               'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
534                               'PLUGIN',
535                               'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
536                               'MULTICAM', 'SPEED', 'ADJUSTMENT'}
537
538     def draw(self, context):
539         layout = self.layout
540
541         strip = act_strip(context)
542
543         seq_type = strip.type
544
545         # draw a filename if we have one
546         if seq_type == 'IMAGE':
547             split = layout.split(percentage=0.2)
548             col = split.column()
549             col.label(text="Path:")
550             col = split.column()
551             col.prop(strip, "directory", text="")
552
553             # Current element for the filename
554
555             elem = strip.getStripElem(context.scene.frame_current)
556             if elem:
557                 split = layout.split(percentage=0.2)
558                 col = split.column()
559                 col.label(text="File:")
560                 col = split.column()
561                 col.prop(elem, "filename", text="")  # strip.elements[0] could be a fallback
562
563         elif seq_type == 'MOVIE':
564             split = layout.split(percentage=0.2)
565             col = split.column()
566             col.label(text="Path:")
567             col = split.column()
568             col.prop(strip, "filepath", text="")
569             col.prop(strip, "mpeg_preseek", text="MPEG Preseek")
570
571         # TODO, sound???
572         # end drawing filename
573
574         layout.prop(strip, "use_translation", text="Image Offset:")
575         if strip.use_translation:
576             col = layout.column(align=True)
577             col.prop(strip.transform, "offset_x", text="X")
578             col.prop(strip.transform, "offset_y", text="Y")
579
580         layout.prop(strip, "use_crop", text="Image Crop:")
581         if strip.use_crop:
582             col = layout.column(align=True)
583             col.prop(strip.crop, "max_y")
584             col.prop(strip.crop, "min_x")
585             col.prop(strip.crop, "min_y")
586             col.prop(strip.crop, "max_x")
587
588         if not isinstance(strip, bpy.types.EffectSequence):
589             col = layout.column(align=True)
590             col.label(text="Trim Duration (hard):")
591             col.prop(strip, "animation_offset_start", text="Start")
592             col.prop(strip, "animation_offset_end", text="End")
593
594         col = layout.column(align=True)
595         col.label(text="Trim Duration (soft):")
596         col.prop(strip, "frame_offset_start", text="Start")
597         col.prop(strip, "frame_offset_end", text="End")
598
599
600 class SEQUENCER_PT_sound(SequencerButtonsPanel, bpy.types.Panel):
601     bl_label = "Sound"
602
603     @classmethod
604     def poll(cls, context):
605         if not cls.has_sequencer(context):
606             return False
607
608         strip = act_strip(context)
609         if not strip:
610             return False
611
612         return (strip.type == 'SOUND')
613
614     def draw(self, context):
615         layout = self.layout
616
617         strip = act_strip(context)
618
619         layout.template_ID(strip, "sound", open="sound.open")
620
621         layout.separator()
622         layout.prop(strip, "filepath", text="")
623
624         row = layout.row()
625         if strip.sound.packed_file:
626             row.operator("sound.unpack", icon='PACKAGE', text="Unpack")
627         else:
628             row.operator("sound.pack", icon='UGLYPACKAGE', text="Pack")
629
630         row.prop(strip.sound, "use_memory_cache")
631
632         layout.prop(strip, "volume")
633         layout.prop(strip, "attenuation")
634
635         col = layout.column(align=True)
636         col.label(text="Trim Duration:")
637         col.prop(strip, "animation_offset_start", text="Start")
638         col.prop(strip, "animation_offset_end", text="End")
639
640
641 class SEQUENCER_PT_scene(SequencerButtonsPanel, bpy.types.Panel):
642     bl_label = "Scene"
643
644     @classmethod
645     def poll(cls, context):
646         if not cls.has_sequencer(context):
647             return False
648
649         strip = act_strip(context)
650         if not strip:
651             return False
652
653         return (strip.type == 'SCENE')
654
655     def draw(self, context):
656         layout = self.layout
657
658         strip = act_strip(context)
659
660         layout.template_ID(strip, "scene")
661
662         scene = strip.scene
663         if scene:
664             layout.prop(scene.render, "use_sequencer")
665
666         layout.label(text="Camera Override")
667         layout.template_ID(strip, "scene_camera")
668
669         if scene:
670             sta = scene.frame_start
671             end = scene.frame_end
672             layout.label(text="Original frame range: %d-%d (%d)" % (sta, end, end - sta + 1))
673
674
675 class SEQUENCER_PT_filter(SequencerButtonsPanel, bpy.types.Panel):
676     bl_label = "Filter"
677
678     @classmethod
679     def poll(cls, context):
680         if not cls.has_sequencer(context):
681             return False
682
683         strip = act_strip(context)
684         if not strip:
685             return False
686
687         return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'META',
688                               'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
689                               'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
690                               'PLUGIN',
691                               'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
692                               'MULTICAM', 'SPEED', 'ADJUSTMENT'}
693
694     def draw(self, context):
695         layout = self.layout
696
697         strip = act_strip(context)
698
699         col = layout.column()
700         col.label(text="Video:")
701         col.prop(strip, "strobe")
702
703         row = layout.row()
704         row.label(text="Flip:")
705         row.prop(strip, "use_flip_x", text="X")
706         row.prop(strip, "use_flip_y", text="Y")
707
708         col = layout.column()
709         col.prop(strip, "use_reverse_frames", text="Backwards")
710         col.prop(strip, "use_deinterlace")
711
712         col = layout.column()
713         col.label(text="Colors:")
714         col.prop(strip, "color_saturation", text="Saturation")
715         col.prop(strip, "color_multiply", text="Multiply")
716         col.prop(strip, "use_premultiply")
717         col.prop(strip, "use_float")
718
719         layout.prop(strip, "use_color_balance")
720         if strip.use_color_balance and strip.color_balance:  # TODO - need to add this somehow
721             row = layout.row()
722             row.active = strip.use_color_balance
723             col = row.column()
724             col.template_color_wheel(strip.color_balance, "lift", value_slider=False, cubic=True)
725             col.row().prop(strip.color_balance, "lift")
726             col.prop(strip.color_balance, "invert_lift", text="Inverse")
727             col = row.column()
728             col.template_color_wheel(strip.color_balance, "gamma", value_slider=False, lock_luminosity=True, cubic=True)
729             col.row().prop(strip.color_balance, "gamma")
730             col.prop(strip.color_balance, "invert_gamma", text="Inverse")
731             col = row.column()
732             col.template_color_wheel(strip.color_balance, "gain", value_slider=False, lock_luminosity=True, cubic=True)
733             col.row().prop(strip.color_balance, "gain")
734             col.prop(strip.color_balance, "invert_gain", text="Inverse")
735
736
737 class SEQUENCER_PT_proxy(SequencerButtonsPanel, bpy.types.Panel):
738     bl_label = "Proxy / Timecode"
739
740     @classmethod
741     def poll(cls, context):
742         if not cls.has_sequencer(context):
743             return False
744
745         strip = act_strip(context)
746         if not strip:
747             return False
748
749         return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'META', 'MULTICAM'}
750
751     def draw_header(self, context):
752         strip = act_strip(context)
753
754         self.layout.prop(strip, "use_proxy", text="")
755
756     def draw(self, context):
757         layout = self.layout
758
759         strip = act_strip(context)
760
761         flow = layout.column_flow()
762         flow.prop(strip, "use_proxy_custom_directory")
763         flow.prop(strip, "use_proxy_custom_file")
764         if strip.proxy:
765             if strip.use_proxy_custom_directory and not strip.use_proxy_custom_file:
766                 flow.prop(strip.proxy, "directory")
767             if strip.use_proxy_custom_file:
768                 flow.prop(strip.proxy, "filepath")
769
770             row = layout.row()
771             row.label(text="Build Sizes:")
772             row.prop(strip.proxy, "build_25")
773             row.prop(strip.proxy, "build_50")
774             row.prop(strip.proxy, "build_75")
775
776             col = layout.column()
777             col.label(text="Build JPEG quality")
778             col.prop(strip.proxy, "quality")
779
780             if strip.type == "MOVIE":
781                 col = layout.column()
782                 col.label(text="Use timecode index:")
783
784                 col.prop(strip.proxy, "timecode")
785
786
787
788 class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, bpy.types.Panel):
789     bl_label = "Scene Preview/Render"
790     bl_space_type = 'SEQUENCE_EDITOR'
791     bl_region_type = 'UI'
792
793     def draw(self, context):
794         layout = self.layout
795         render = context.scene.render
796
797         col = layout.column()
798         col.active = False  # Currently only opengl preview works!
799         col.prop(render, "use_sequencer_gl_preview", text="Open GL Preview")
800         col = layout.column()
801         #col.active = render.use_sequencer_gl_preview
802         col.prop(render, "sequencer_gl_preview", text="")
803
804         '''
805         col = layout.column()
806         col.prop(render, "use_sequencer_gl_render", text="Open GL Render")
807         col = layout.column()
808         col.active = render.use_sequencer_gl_render
809         col.prop(render, "sequencer_gl_render", text="")
810         '''
811
812
813 class SEQUENCER_PT_view(SequencerButtonsPanel_Output, bpy.types.Panel):
814     bl_label = "View Settings"
815
816     def draw(self, context):
817         layout = self.layout
818
819         st = context.space_data
820
821         col = layout.column()
822         if st.display_mode == 'IMAGE':
823             col.prop(st, "draw_overexposed")  # text="Zebra"
824             col.prop(st, "show_safe_margin")
825         if st.display_mode == 'WAVEFORM':
826             col.prop(st, "show_separate_color")
827         col.prop(st, "proxy_render_size")
828
829 if __name__ == "__main__":  # only for live edit.
830     bpy.utils.register_module(__name__)