1 # ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17 # ##### END GPL LICENSE BLOCK #####
23 def act_strip(context):
25 return context.scene.sequence_editor.active_strip
26 except AttributeError:
30 class SEQUENCER_HT_header(bpy.types.Header):
31 bl_space_type = 'SEQUENCE_EDITOR'
33 def draw(self, context):
36 st = context.space_data
38 row = layout.row(align=True)
41 if context.area.show_menus:
42 sub = row.row(align=True)
43 sub.menu("SEQUENCER_MT_view")
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")
53 layout.prop(st, "view_type", expand=True, text="")
55 if (st.view_type == 'PREVIEW') or (st.view_type == 'SEQUENCER_PREVIEW'):
56 layout.prop(st, "display_mode", expand=True, text="")
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')
64 layout.operator("sequencer.refresh_all")
65 elif (st.view_type == 'SEQUENCER_PREVIEW'):
67 layout.operator("sequencer.refresh_all")
68 layout.prop(st, "display_channel", text="Channel")
70 layout.prop(st, "display_channel", text="Channel")
73 class SEQUENCER_MT_view_toggle(bpy.types.Menu):
74 bl_label = "View Type"
76 def draw(self, context):
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'
84 class SEQUENCER_MT_view(bpy.types.Menu):
87 def draw(self, context):
90 st = context.space_data
95 uiBlock *block= uiBeginBlock(C, ar, "seq_viewmenu", UI_EMBOSSP);
96 short yco= 0, menuwidth=120;
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, "");
105 uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL,
106 "Grease Pencil...", 0, yco-=20,
107 menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
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, "");
115 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
116 "Play Back Animation in all "
117 "3D Views and Sequence Areas|Alt Shift A",
119 menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
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")
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")
139 layout.prop(st, "use_marker_sync")
142 layout.operator("screen.area_dupli")
143 layout.operator("screen.screen_full_area")
146 class SEQUENCER_MT_select(bpy.types.Menu):
149 def draw(self, context):
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'
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'
160 layout.operator("sequencer.select_linked")
161 layout.operator("sequencer.select_all_toggle")
162 layout.operator("sequencer.select_inverse")
165 class SEQUENCER_MT_marker(bpy.types.Menu):
168 def draw(self, context):
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")
177 layout.label(text="ToDo: Name Marker")
179 #layout.operator("sequencer.sound_strip_add", text="Transform Markers") # toggle, will be rna - (sseq->flag & SEQ_MARKER_TRANS)
182 class SEQUENCER_MT_add(bpy.types.Menu):
185 def draw(self, context):
187 layout.operator_context = 'INVOKE_REGION_WIN'
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")
195 layout.menu("SEQUENCER_MT_add_effect")
198 class SEQUENCER_MT_add_effect(bpy.types.Menu):
199 bl_label = "Effect Strip..."
201 def draw(self, context):
203 layout.operator_context = 'INVOKE_REGION_WIN'
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'
223 class SEQUENCER_MT_strip(bpy.types.Menu):
226 def draw(self, context):
229 layout.operator_context = 'INVOKE_REGION_WIN'
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
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")
242 layout.operator("sequencer.duplicate")
243 layout.operator("sequencer.delete")
245 strip = act_strip(context)
250 # XXX note strip.type is never equal to 'EFFECT', look at seq_type_items within rna_sequencer.c
251 if stype == 'EFFECT':
254 # layout.operator("sequencer.effect_change")
255 # layout.operator("sequencer.effect_reassign_inputs")
256 elif stype == 'IMAGE':
258 # layout.operator("sequencer.image_change")
259 layout.operator("sequencer.rendersize")
260 elif stype == 'SCENE':
263 # layout.operator("sequencer.scene_change", text="Change Scene")
264 elif stype == 'MOVIE':
266 # layout.operator("sequencer.movie_change")
267 layout.operator("sequencer.rendersize")
271 layout.operator("sequencer.meta_make")
272 layout.operator("sequencer.meta_separate")
274 #if (ed && (ed->metastack.first || (ed->act_seq && ed->act_seq->type == SEQ_META))) {
276 # uiItemO(layout, NULL, 0, "sequencer.meta_toggle");
280 layout.operator("sequencer.reload")
282 layout.operator("sequencer.lock")
283 layout.operator("sequencer.unlock")
284 layout.operator("sequencer.mute")
285 layout.operator("sequencer.unmute")
287 layout.operator("sequencer.mute", text="Mute Deselected Strips").unselected = True
289 layout.operator("sequencer.snap")
291 layout.operator_menu_enum("sequencer.swap", "side")
294 class SequencerButtonsPanel(bpy.types.Panel):
295 bl_space_type = 'SEQUENCE_EDITOR'
296 bl_region_type = 'UI'
298 def has_sequencer(self, context):
299 return (context.space_data.view_type == 'SEQUENCER') or (context.space_data.view_type == 'SEQUENCER_PREVIEW')
301 def poll(self, context):
302 return self.has_sequencer(context) and (act_strip(context) is not None)
305 class SequencerButtonsPanel_Output(bpy.types.Panel):
306 bl_space_type = 'SEQUENCE_EDITOR'
307 bl_region_type = 'UI'
309 def has_preview(self, context):
310 return (context.space_data.view_type == 'PREVIEW') or (context.space_data.view_type == 'SEQUENCER_PREVIEW')
312 def poll(self, context):
313 return self.has_preview(context)
316 class SEQUENCER_PT_edit(SequencerButtonsPanel):
317 bl_label = "Edit Strip"
319 def draw(self, context):
321 render = context.scene.render
322 strip = act_strip(context)
324 split = layout.split(percentage=0.3)
325 split.label(text="Name:")
326 split.prop(strip, "name", text="")
328 split = layout.split(percentage=0.3)
329 split.label(text="Type:")
330 split.prop(strip, "type", text="")
332 split = layout.split(percentage=0.3)
333 split.label(text="Blend:")
334 split.prop(strip, "blend_mode", text="")
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="")
343 sub.active = (not strip.mute)
345 sub.prop(strip, "blend_opacity", text="Opacity", slider=True)
348 row.prop(strip, "lock")
349 row.prop(strip, "frame_locked", text="Frame Lock")
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)))
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")
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")
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'
375 def draw(self, context):
377 render = context.scene.render
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="")
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="")
392 class SEQUENCER_PT_effect(SequencerButtonsPanel):
393 bl_label = "Effect Strip"
395 def poll(self, context):
396 if not self.has_sequencer(context):
399 strip = act_strip(context)
403 return strip.type in ('ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
404 'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
406 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', 'SPEED',
409 def draw(self, context):
412 strip = act_strip(context)
414 if strip.type == 'COLOR':
415 layout.prop(strip, "color")
417 elif strip.type == 'WIPE':
419 col = layout.column()
420 col.prop(strip, "transition_type")
421 col.label(text="Direction:")
422 col.row().prop(strip, "direction", expand=True)
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")
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")
437 row.prop(strip, "quality", slider=True)
438 row.prop(strip, "only_boost")
440 elif strip.type == 'SPEED':
441 layout.prop(strip, "global_speed")
443 flow = layout.column_flow()
444 flow.prop(strip, "curve_velocity")
445 flow.prop(strip, "curve_compress_y")
446 flow.prop(strip, "frame_blending")
448 elif strip.type == 'TRANSFORM':
449 self.draw_panel_transform(strip)
451 elif strip.type == "MULTICAM":
452 layout.prop(strip, "multicam_source")
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")
462 def draw_panel_transform(self, strip):
464 col = layout.column()
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")
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")
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")
488 col = layout.column(align=True)
489 col.label(text="Rotation:")
490 col.prop(strip, "rotation_start", text="Rotation")
493 class SEQUENCER_PT_input(SequencerButtonsPanel):
494 bl_label = "Strip Input"
496 def poll(self, context):
497 if not self.has_sequencer(context):
500 strip = act_strip(context)
504 return strip.type in ('MOVIE', 'IMAGE', 'SCENE', 'META',
505 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
506 'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
508 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
511 def draw_filename(self, context):
514 def draw(self, context):
517 strip = act_strip(context)
519 self.draw_filename(context)
521 layout.prop(strip, "use_translation", text="Image Offset:")
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")
528 layout.prop(strip, "use_crop", text="Image 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")
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")
543 class SEQUENCER_PT_input_movie(SEQUENCER_PT_input):
544 bl_label = "Strip Input"
546 def poll(self, context):
547 if not self.has_sequencer(context):
550 strip = act_strip(context)
554 return strip.type == 'MOVIE'
556 def draw_filename(self, context):
559 strip = act_strip(context)
561 split = layout.split(percentage=0.2)
563 col.label(text="Path:")
565 col.prop(strip, "filepath", text="")
568 class SEQUENCER_PT_input_image(SEQUENCER_PT_input):
569 bl_label = "Strip Input"
571 def poll(self, context):
572 if not self.has_sequencer(context):
575 strip = act_strip(context)
579 return strip.type == 'IMAGE'
581 def draw_filename(self, context):
584 strip = act_strip(context)
586 split = layout.split(percentage=0.2)
588 col.label(text="Path:")
590 col.prop(strip, "directory", text="")
592 # Current element for the filename
594 elem = strip.getStripElem(context.scene.frame_current)
596 split = layout.split(percentage=0.2)
598 col.label(text="File:")
600 col.prop(elem, "filename", text="") # strip.elements[0] could be a fallback
602 class SEQUENCER_PT_input_secondary(SEQUENCER_PT_input):
603 bl_label = "Strip Input"
605 def poll(self, context):
606 if not self.has_sequencer(context):
609 strip = act_strip(context)
613 return strip.type in ('SCENE', 'META')
615 def draw_filename(self, context):
618 class SEQUENCER_PT_sound(SequencerButtonsPanel):
621 def poll(self, context):
622 if not self.has_sequencer(context):
625 strip = act_strip(context)
629 return (strip.type == 'SOUND')
631 def draw(self, context):
634 strip = act_strip(context)
636 layout.template_ID(strip, "sound", open="sound.open")
639 layout.prop(strip, "filepath", text="")
642 if strip.sound.packed_file:
643 row.operator("sound.unpack", icon='PACKAGE', text="Unpack")
645 row.operator("sound.pack", icon='UGLYPACKAGE', text="Pack")
647 row.prop(strip.sound, "caching")
649 layout.prop(strip, "volume")
652 class SEQUENCER_PT_scene(SequencerButtonsPanel):
655 def poll(self, context):
656 if not self.has_sequencer(context):
659 strip = act_strip(context)
663 return (strip.type == 'SCENE')
665 def draw(self, context):
668 strip = act_strip(context)
670 layout.template_ID(strip, "scene")
672 layout.label(text="Camera Override")
673 layout.template_ID(strip, "scene_camera")
676 class SEQUENCER_PT_filter(SequencerButtonsPanel):
679 def poll(self, context):
680 if not self.has_sequencer(context):
683 strip = act_strip(context)
687 return strip.type in ('MOVIE', 'IMAGE', 'SCENE', 'META',
688 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
689 'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
691 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
694 def draw(self, context):
697 strip = act_strip(context)
699 col = layout.column()
700 col.label(text="Video:")
701 col.prop(strip, "strobe")
704 row.label(text="Flip:")
705 row.prop(strip, "flip_x", text="X")
706 row.prop(strip, "flip_y", text="Y")
708 col = layout.column()
709 col.prop(strip, "reverse_frames", text="Backwards")
710 col.prop(strip, "de_interlace")
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")
718 layout.prop(strip, "use_color_balance")
719 if strip.color_balance: # TODO - need to add this somehow
721 row.active = strip.use_color_balance
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")
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")
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")
736 class SEQUENCER_PT_proxy(SequencerButtonsPanel):
739 def poll(self, context):
740 if not self.has_sequencer(context):
743 strip = act_strip(context)
747 return strip.type in ('MOVIE', 'IMAGE', 'SCENE', 'META', 'MULTICAM')
749 def draw_header(self, context):
750 strip = act_strip(context)
752 self.layout.prop(strip, "use_proxy", text="")
754 def draw(self, context):
757 strip = act_strip(context)
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")
769 class SEQUENCER_PT_view(SequencerButtonsPanel_Output):
770 bl_label = "View Settings"
772 def draw(self, context):
775 st = context.space_data
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")
786 SEQUENCER_HT_header, # header/menu classes
788 SEQUENCER_MT_view_toggle,
792 SEQUENCER_MT_add_effect,
795 SEQUENCER_PT_edit, # sequencer panels
796 SEQUENCER_PT_preview,
798 SEQUENCER_PT_input_movie,
799 SEQUENCER_PT_input_image,
800 SEQUENCER_PT_input_secondary,
806 SEQUENCER_PT_view] # view panels
810 register = bpy.types.register
816 unregister = bpy.types.unregister
820 if __name__ == "__main__":