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