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