99844f87a325480b00251ad2810060368d285125
[blender-staging.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.separator()
241
242         layout.operator("sequencer.duplicate")
243         layout.operator("sequencer.delete")
244
245         strip = act_strip(context)
246
247         if strip:
248             stype = strip.type
249
250             # XXX note strip.type is never equal to 'EFFECT', look at seq_type_items within rna_sequencer.c
251             if stype == 'EFFECT':
252                 pass
253                 # layout.separator()
254                 # layout.operator("sequencer.effect_change")
255                 # layout.operator("sequencer.effect_reassign_inputs")
256             elif stype == 'IMAGE':
257                 layout.separator()
258                 # layout.operator("sequencer.image_change")
259                 layout.operator("sequencer.rendersize")
260             elif stype == 'SCENE':
261                 pass
262                 # layout.separator()
263                 # layout.operator("sequencer.scene_change", text="Change Scene")
264             elif stype == 'MOVIE':
265                 layout.separator()
266                 # layout.operator("sequencer.movie_change")
267                 layout.operator("sequencer.rendersize")
268
269         layout.separator()
270
271         layout.operator("sequencer.meta_make")
272         layout.operator("sequencer.meta_separate")
273
274         #if (ed && (ed->metastack.first || (ed->act_seq && ed->act_seq->type == SEQ_META))) {
275         #       uiItemS(layout);
276         #       uiItemO(layout, NULL, 0, "sequencer.meta_toggle");
277         #}
278
279         layout.separator()
280         layout.operator("sequencer.reload")
281         layout.separator()
282         layout.operator("sequencer.lock")
283         layout.operator("sequencer.unlock")
284         layout.operator("sequencer.mute")
285         layout.operator("sequencer.unmute")
286
287         layout.operator("sequencer.mute", text="Mute Deselected Strips").unselected = True
288
289         layout.operator("sequencer.snap")
290
291         layout.operator_menu_enum("sequencer.swap", "side")
292
293
294 class SequencerButtonsPanel(bpy.types.Panel):
295     bl_space_type = 'SEQUENCE_EDITOR'
296     bl_region_type = 'UI'
297
298     def has_sequencer(self, context):
299         return (context.space_data.view_type == 'SEQUENCER') or (context.space_data.view_type == 'SEQUENCER_PREVIEW')
300
301     def poll(self, context):
302         return self.has_sequencer(context) and (act_strip(context) is not None)
303
304
305 class SequencerButtonsPanel_Output(bpy.types.Panel):
306     bl_space_type = 'SEQUENCE_EDITOR'
307     bl_region_type = 'UI'
308
309     def has_preview(self, context):
310         return (context.space_data.view_type == 'PREVIEW') or (context.space_data.view_type == 'SEQUENCER_PREVIEW')
311
312     def poll(self, context):
313         return self.has_preview(context)
314
315
316 class SEQUENCER_PT_edit(SequencerButtonsPanel):
317     bl_label = "Edit Strip"
318
319     def draw(self, context):
320         layout = self.layout
321         render = context.scene.render
322         strip = act_strip(context)
323
324         split = layout.split(percentage=0.3)
325         split.label(text="Name:")
326         split.prop(strip, "name", text="")
327
328         split = layout.split(percentage=0.3)
329         split.label(text="Type:")
330         split.prop(strip, "type", text="")
331
332         split = layout.split(percentage=0.3)
333         split.label(text="Blend:")
334         split.prop(strip, "blend_mode", text="")
335
336         row = layout.row()
337         if strip.mute == True:
338             row.prop(strip, "mute", toggle=True, icon='RESTRICT_VIEW_ON', text="")
339         elif strip.mute is False:
340             row.prop(strip, "mute", toggle=True, icon='RESTRICT_VIEW_OFF', text="")
341
342         sub = row.row()
343         sub.active = (not strip.mute)
344
345         sub.prop(strip, "blend_opacity", text="Opacity", slider=True)
346
347         row = layout.row()
348         row.prop(strip, "lock")
349         row.prop(strip, "frame_locked", text="Frame Lock")
350
351         col = layout.column()
352         col.enabled = not strip.lock
353         col.prop(strip, "channel")
354         col.prop(strip, "frame_start")
355         subrow = col.split(percentage=0.66)
356         subrow.prop(strip, "length")
357         subrow.label(text="%.2f sec" % (strip.length / (render.fps / render.fps_base)))
358
359         col = layout.column(align=True)
360         col.label(text="Offset:")
361         col.prop(strip, "frame_offset_start", text="Start")
362         col.prop(strip, "frame_offset_end", text="End")
363
364         col = layout.column(align=True)
365         col.label(text="Still:")
366         col.prop(strip, "frame_still_start", text="Start")
367         col.prop(strip, "frame_still_end", text="End")
368
369
370 class SEQUENCER_PT_preview(bpy.types.Panel):
371     bl_label = "Scene Preview/Render"
372     bl_space_type = 'SEQUENCE_EDITOR'
373     bl_region_type = 'UI'
374
375     def draw(self, context):
376         layout = self.layout
377         render = context.scene.render
378
379         col = layout.column()
380         col.prop(render, "use_sequencer_gl_preview", text="Open GL Preview")
381         col = layout.column()
382         col.active = render.use_sequencer_gl_preview
383         col.prop(render, "sequencer_gl_preview", text="")
384
385         col = layout.column()
386         col.prop(render, "use_sequencer_gl_render", text="Open GL Render")
387         col = layout.column()
388         col.active = render.use_sequencer_gl_render
389         col.prop(render, "sequencer_gl_render", text="")
390
391
392 class SEQUENCER_PT_effect(SequencerButtonsPanel):
393     bl_label = "Effect Strip"
394
395     def poll(self, context):
396         if not self.has_sequencer(context):
397             return False
398
399         strip = act_strip(context)
400         if not strip:
401             return False
402
403         return strip.type in ('ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
404                               'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
405                               'PLUGIN',
406                               'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', 'SPEED',
407                               'MULTICAM')
408
409     def draw(self, context):
410         layout = self.layout
411
412         strip = act_strip(context)
413
414         if strip.type == 'COLOR':
415             layout.prop(strip, "color")
416
417         elif strip.type == 'WIPE':
418
419             col = layout.column()
420             col.prop(strip, "transition_type")
421             col.label(text="Direction:")
422             col.row().prop(strip, "direction", expand=True)
423
424             col = layout.column()
425             col.prop(strip, "blur_width", slider=True)
426             if strip.transition_type in ('SINGLE', 'DOUBLE'):
427                 col.prop(strip, "angle")
428
429         elif strip.type == 'GLOW':
430             flow = layout.column_flow()
431             flow.prop(strip, "threshold", slider=True)
432             flow.prop(strip, "clamp", slider=True)
433             flow.prop(strip, "boost_factor")
434             flow.prop(strip, "blur_distance")
435
436             row = layout.row()
437             row.prop(strip, "quality", slider=True)
438             row.prop(strip, "only_boost")
439
440         elif strip.type == 'SPEED':
441             layout.prop(strip, "global_speed")
442
443             flow = layout.column_flow()
444             flow.prop(strip, "curve_velocity")
445             flow.prop(strip, "curve_compress_y")
446             flow.prop(strip, "frame_blending")
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         col = layout.column(align=True)
455         if strip.type == 'SPEED':
456             col.prop(strip, "speed_fader", text="Speed fader")
457         elif strip.type in ('CROSS', 'GAMMA_CROSS', 'PLUGIN', 'WIPE'):
458                 col.prop(strip, "use_effect_default_fade", "Default fade")
459                 if not strip.use_effect_default_fade:
460                     col.prop(strip, "effect_fader", text="Effect fader")
461
462     def draw_panel_transform(self, strip):
463         layout = self.layout
464         col = layout.column()
465
466         col.prop(strip, "interpolation")
467         col.prop(strip, "translation_unit")
468         col = layout.column(align=True)
469         col.label(text="Position:")
470         col.prop(strip, "translate_start_x", text="X")
471         col.prop(strip, "translate_start_y", text="Y")
472
473         layout.separator()
474
475         col = layout.column(align=True)
476         col.prop(strip, "uniform_scale")
477         if (strip.uniform_scale):
478             col = layout.column(align=True)
479             col.prop(strip, "scale_start_x", text="Scale")
480         else:
481             col = layout.column(align=True)
482             col.label(text="Scale:")
483             col.prop(strip, "scale_start_x", text="X")
484             col.prop(strip, "scale_start_y", text="Y")
485
486         layout.separator()
487
488         col = layout.column(align=True)
489         col.label(text="Rotation:")
490         col.prop(strip, "rotation_start", text="Rotation")
491
492
493 class SEQUENCER_PT_input(SequencerButtonsPanel):
494     bl_label = "Strip Input"
495
496     def poll(self, context):
497         if not self.has_sequencer(context):
498             return False
499
500         strip = act_strip(context)
501         if not strip:
502             return False
503
504         return strip.type in ('MOVIE', 'IMAGE', 'SCENE', 'META',
505                               'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
506                               'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
507                               'PLUGIN',
508                               'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
509                               'MULTICAM','SPEED')
510
511     def draw_filename(self, context):
512         pass
513
514     def draw(self, context):
515         layout = self.layout
516
517         strip = act_strip(context)
518
519         self.draw_filename(context)
520
521         layout.prop(strip, "use_translation", text="Image Offset:")
522         if strip.transform:
523             col = layout.column(align=True)
524             col.active = strip.use_translation
525             col.prop(strip.transform, "offset_x", text="X")
526             col.prop(strip.transform, "offset_y", text="Y")
527
528         layout.prop(strip, "use_crop", text="Image Crop:")
529         if strip.crop:
530             col = layout.column(align=True)
531             col.active = strip.use_crop
532             col.prop(strip.crop, "top")
533             col.prop(strip.crop, "left")
534             col.prop(strip.crop, "bottom")
535             col.prop(strip.crop, "right")
536
537         col = layout.column(align=True)
538         col.label(text="Trim Duration:")
539         col.prop(strip, "animation_start_offset", text="Start")
540         col.prop(strip, "animation_end_offset", text="End")
541
542
543 class SEQUENCER_PT_input_movie(SEQUENCER_PT_input):
544     bl_label = "Strip Input"
545
546     def poll(self, context):
547         if not self.has_sequencer(context):
548             return False
549
550         strip = act_strip(context)
551         if not strip:
552             return False
553
554         return strip.type == 'MOVIE'
555
556     def draw_filename(self, context):
557         layout = self.layout
558
559         strip = act_strip(context)
560
561         split = layout.split(percentage=0.2)
562         col = split.column()
563         col.label(text="Path:")
564         col = split.column()
565         col.prop(strip, "filepath", text="")
566
567
568 class SEQUENCER_PT_input_image(SEQUENCER_PT_input):
569     bl_label = "Strip Input"
570
571     def poll(self, context):
572         if not self.has_sequencer(context):
573             return False
574
575         strip = act_strip(context)
576         if not strip:
577             return False
578
579         return strip.type == 'IMAGE'
580
581     def draw_filename(self, context):
582         layout = self.layout
583
584         strip = act_strip(context)
585
586         split = layout.split(percentage=0.2)
587         col = split.column()
588         col.label(text="Path:")
589         col = split.column()
590         col.prop(strip, "directory", text="")
591
592         # Current element for the filename
593
594         elem = strip.getStripElem(context.scene.frame_current)
595         if elem:
596             split = layout.split(percentage=0.2)
597             col = split.column()
598             col.label(text="File:")
599             col = split.column()
600             col.prop(elem, "filename", text="") # strip.elements[0] could be a fallback
601
602 class SEQUENCER_PT_input_secondary(SEQUENCER_PT_input):
603     bl_label = "Strip Input"
604
605     def poll(self, context):
606         if not self.has_sequencer(context):
607             return False
608
609         strip = act_strip(context)
610         if not strip:
611             return False
612
613         return strip.type in ('SCENE', 'META')
614
615     def draw_filename(self, context):
616         pass
617
618 class SEQUENCER_PT_sound(SequencerButtonsPanel):
619     bl_label = "Sound"
620
621     def poll(self, context):
622         if not self.has_sequencer(context):
623             return False
624
625         strip = act_strip(context)
626         if not strip:
627             return False
628
629         return (strip.type == 'SOUND')
630
631     def draw(self, context):
632         layout = self.layout
633
634         strip = act_strip(context)
635
636         layout.template_ID(strip, "sound", open="sound.open")
637
638         layout.separator()
639         layout.prop(strip, "filepath", text="")
640
641         row = layout.row()
642         if strip.sound.packed_file:
643             row.operator("sound.unpack", icon='PACKAGE', text="Unpack")
644         else:
645             row.operator("sound.pack", icon='UGLYPACKAGE', text="Pack")
646
647         row.prop(strip.sound, "caching")
648
649         layout.prop(strip, "volume")
650
651
652 class SEQUENCER_PT_scene(SequencerButtonsPanel):
653     bl_label = "Scene"
654
655     def poll(self, context):
656         if not self.has_sequencer(context):
657             return False
658
659         strip = act_strip(context)
660         if not strip:
661             return False
662
663         return (strip.type == 'SCENE')
664
665     def draw(self, context):
666         layout = self.layout
667
668         strip = act_strip(context)
669
670         layout.template_ID(strip, "scene")
671
672         layout.label(text="Camera Override")
673         layout.template_ID(strip, "scene_camera")
674
675
676 class SEQUENCER_PT_filter(SequencerButtonsPanel):
677     bl_label = "Filter"
678
679     def poll(self, context):
680         if not self.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')
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, "flip_x", text="X")
706         row.prop(strip, "flip_y", text="Y")
707
708         col = layout.column()
709         col.prop(strip, "reverse_frames", text="Backwards")
710         col.prop(strip, "de_interlace")
711
712         col = layout.column()
713         col.label(text="Colors:")
714         col.prop(strip, "multiply_colors", text="Multiply")
715         col.prop(strip, "premultiply")
716         col.prop(strip, "convert_float")
717
718         layout.prop(strip, "use_color_balance")
719         if strip.color_balance: # TODO - need to add this somehow
720             row = layout.row()
721             row.active = strip.use_color_balance
722             col = row.column()
723             col.template_color_wheel(strip.color_balance, "lift", value_slider=False)
724             col.row().prop(strip.color_balance, "lift")
725             col.prop(strip.color_balance, "inverse_lift", text="Inverse")
726             col = row.column()
727             col.template_color_wheel(strip.color_balance, "gamma", value_slider=False)
728             col.row().prop(strip.color_balance, "gamma")
729             col.prop(strip.color_balance, "inverse_gamma", text="Inverse")
730             col = row.column()
731             col.template_color_wheel(strip.color_balance, "gain", value_slider=False)
732             col.row().prop(strip.color_balance, "gain")
733             col.prop(strip.color_balance, "inverse_gain", text="Inverse")
734
735
736 class SEQUENCER_PT_proxy(SequencerButtonsPanel):
737     bl_label = "Proxy"
738
739     def poll(self, context):
740         if not self.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, "proxy_custom_directory")
761         flow.prop(strip, "proxy_custom_file")
762         if strip.proxy: # TODO - need to add this somehow
763             if strip.proxy_custom_directory and not strip.proxy_custom_file:
764                 flow.prop(strip.proxy, "directory")
765             if strip.proxy_custom_file:
766                 flow.prop(strip.proxy, "filepath")
767
768
769 class SEQUENCER_PT_view(SequencerButtonsPanel_Output):
770     bl_label = "View Settings"
771
772     def draw(self, context):
773         layout = self.layout
774
775         st = context.space_data
776
777         col = layout.column()
778         if st.display_mode == 'IMAGE':
779             col.prop(st, "draw_overexposed") # text="Zebra"
780             col.prop(st, "draw_safe_margin")
781         if st.display_mode == 'WAVEFORM':
782             col.prop(st, "separate_color_preview")
783         col.prop(st, "proxy_render_size")
784
785 classes = [
786     SEQUENCER_HT_header, # header/menu classes
787     SEQUENCER_MT_view,
788     SEQUENCER_MT_view_toggle,
789     SEQUENCER_MT_select,
790     SEQUENCER_MT_marker,
791     SEQUENCER_MT_add,
792     SEQUENCER_MT_add_effect,
793     SEQUENCER_MT_strip,
794
795     SEQUENCER_PT_edit, # sequencer panels
796     SEQUENCER_PT_preview,
797     SEQUENCER_PT_effect,
798     SEQUENCER_PT_input_movie,
799     SEQUENCER_PT_input_image,
800     SEQUENCER_PT_input_secondary,
801     SEQUENCER_PT_sound,
802     SEQUENCER_PT_scene,
803     SEQUENCER_PT_filter,
804     SEQUENCER_PT_proxy,
805
806     SEQUENCER_PT_view] # view panels
807
808
809 def register():
810     register = bpy.types.register
811     for cls in classes:
812         register(cls)
813
814
815 def unregister():
816     unregister = bpy.types.unregister
817     for cls in classes:
818         unregister(cls)
819
820 if __name__ == "__main__":
821     register()