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