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