12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090 |
- # ##### BEGIN GPL LICENSE BLOCK #####
- #
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License
- # as published by the Free Software Foundation; either version 2
- # of the License, or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software Foundation,
- # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- #
- # ##### END GPL LICENSE BLOCK #####
- # <pep8 compliant>
- import bpy
- from bpy.types import (
- Header,
- Menu,
- Panel,
- )
- from bpy.app.translations import (
- contexts as i18n_contexts,
- pgettext_iface as iface_,
- )
- from bl_ui.properties_grease_pencil_common import (
- AnnotationDataPanel,
- GreasePencilToolsPanel,
- )
- from rna_prop_ui import PropertyPanel
- def act_strip(context):
- try:
- return context.scene.sequence_editor.active_strip
- except AttributeError:
- return None
- def selected_sequences_len(context):
- selected_sequences = getattr(context, "selected_sequences", None)
- if selected_sequences is None:
- return 0
- return len(selected_sequences)
- def draw_color_balance(layout, color_balance):
- layout.use_property_split = False
- flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
- col = flow.column()
- box = col.box()
- split = box.split(factor=0.35)
- col = split.column(align=True)
- col.label(text="Lift:")
- col.separator()
- col.separator()
- col.prop(color_balance, "lift", text="")
- col.prop(color_balance, "invert_lift", text="Invert", icon='ARROW_LEFTRIGHT')
- split.template_color_picker(color_balance, "lift", value_slider=True, cubic=True)
- col = flow.column()
- box = col.box()
- split = box.split(factor=0.35)
- col = split.column(align=True)
- col.label(text="Gamma:")
- col.separator()
- col.separator()
- col.prop(color_balance, "gamma", text="")
- col.prop(color_balance, "invert_gamma", text="Invert", icon='ARROW_LEFTRIGHT')
- split.template_color_picker(color_balance, "gamma", value_slider=True, lock_luminosity=True, cubic=True)
- col = flow.column()
- box = col.box()
- split = box.split(factor=0.35)
- col = split.column(align=True)
- col.label(text="Gain:")
- col.separator()
- col.separator()
- col.prop(color_balance, "gain", text="")
- col.prop(color_balance, "invert_gain", text="Invert", icon='ARROW_LEFTRIGHT')
- split.template_color_picker(color_balance, "gain", value_slider=True, lock_luminosity=True, cubic=True)
- class SEQUENCER_HT_header(Header):
- bl_space_type = 'SEQUENCE_EDITOR'
- def draw(self, context):
- layout = self.layout
- st = context.space_data
- layout.template_header()
- layout.prop(st, "view_type", text="")
- SEQUENCER_MT_editor_menus.draw_collapsible(context, layout)
- layout.separator_spacer()
- if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
- layout.prop(st, "display_mode", text="", icon_only=True)
- if st.view_type != 'SEQUENCER':
- layout.prop(st, "preview_channels", text="", icon_only=True)
- if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
- gpd = context.gpencil_data
- tool_settings = context.tool_settings
- # Proportional editing
- if gpd and gpd.use_stroke_edit_mode:
- row = layout.row(align=True)
- row.prop(tool_settings, "use_proportional_edit", icon_only=True)
- if tool_settings.use_proportional_edit:
- row.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
- class SEQUENCER_MT_editor_menus(Menu):
- bl_idname = "SEQUENCER_MT_editor_menus"
- bl_label = ""
- def draw(self, context):
- layout = self.layout
- st = context.space_data
- layout.menu("SEQUENCER_MT_view")
- if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
- layout.menu("SEQUENCER_MT_select")
- layout.menu("SEQUENCER_MT_marker")
- layout.menu("SEQUENCER_MT_add")
- layout.menu("SEQUENCER_MT_strip")
- class SEQUENCER_MT_view_toggle(Menu):
- bl_label = "View Type"
- def draw(self, _context):
- layout = self.layout
- layout.operator("sequencer.view_toggle").type = 'SEQUENCER'
- layout.operator("sequencer.view_toggle").type = 'PREVIEW'
- layout.operator("sequencer.view_toggle").type = 'SEQUENCER_PREVIEW'
- class SEQUENCER_MT_view_cache(Menu):
- bl_label = "Cache"
- def draw(self, context):
- layout = self.layout
- ed = context.scene.sequence_editor
- layout.prop(ed, "show_cache")
- layout.separator()
- col = layout.column()
- col.enabled = ed.show_cache
- col.prop(ed, "show_cache_final_out")
- col.prop(ed, "show_cache_raw")
- col.prop(ed, "show_cache_preprocessed")
- col.prop(ed, "show_cache_composite")
- class SEQUENCER_MT_range(Menu):
- bl_label = "Range"
- def draw(self, _context):
- layout = self.layout
- layout.operator("anim.previewrange_set", text="Set Preview Range")
- layout.operator("anim.previewrange_clear", text="Clear Preview Range")
- layout.separator()
- layout.operator("anim.start_frame_set", text="Set Start Frame")
- layout.operator("anim.end_frame_set", text="Set End Frame")
- class SEQUENCER_MT_view(Menu):
- bl_label = "View"
- def draw(self, context):
- layout = self.layout
- st = context.space_data
- is_preview = st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}
- is_sequencer_view = st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}
- if st.view_type == 'PREVIEW':
- # Specifying the REGION_PREVIEW context is needed in preview-only
- # mode, else the lookup for the shortcut will fail in
- # wm_keymap_item_find_props() (see #32595).
- layout.operator_context = 'INVOKE_REGION_PREVIEW'
- layout.prop(st, "show_region_ui")
- layout.operator_context = 'INVOKE_DEFAULT'
- if st.view_type == 'SEQUENCER':
- layout.prop(st, "show_backdrop", text="Preview as Backdrop")
- layout.separator()
- if is_sequencer_view:
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("sequencer.view_selected", text="Frame Selected")
- layout.operator("sequencer.view_all", text="Frame All")
- layout.operator("view2d.zoom_border", text="Zoom")
- layout.separator()
- layout.operator_context = 'INVOKE_DEFAULT'
- layout.menu("SEQUENCER_MT_navigation")
- layout.menu("SEQUENCER_MT_range")
- layout.separator()
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("sequencer.refresh_all", icon='FILE_REFRESH', text="Refresh All")
- layout.separator()
- layout.operator_context = 'INVOKE_DEFAULT'
- if is_preview:
- layout.operator_context = 'INVOKE_REGION_PREVIEW'
- layout.operator("sequencer.view_all_preview", text="Fit Preview in window")
- layout.operator("view2d.zoom_border", text="Zoom")
- layout.separator()
- ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
- for a, b in ratios:
- layout.operator(
- "sequencer.view_zoom_ratio",
- text=iface_("Zoom %d:%d") % (a, b),
- translate=False,
- ).ratio = a / b
- layout.separator()
- layout.operator_context = 'INVOKE_DEFAULT'
- # # XXX, invokes in the header view
- # layout.operator("sequencer.view_ghost_border", text="Overlay Border")
- if is_sequencer_view:
- layout.prop(st, "show_seconds")
- layout.prop(st, "show_frame_indicator")
- layout.prop(st, "show_strip_offset")
- layout.prop(st, "show_marker_lines")
- layout.separator()
- layout.menu("SEQUENCER_MT_view_cache")
- layout.prop_menu_enum(st, "waveform_display_type")
- if is_preview:
- if st.display_mode == 'IMAGE':
- layout.prop(st, "show_safe_areas")
- layout.prop(st, "show_metadata")
- elif st.display_mode == 'WAVEFORM':
- layout.prop(st, "show_separate_color")
- layout.separator()
- layout.operator("render.opengl", text="Sequence Render Image", icon='RENDER_STILL').sequencer = True
- props = layout.operator("render.opengl", text="Sequence Render Animation", icon='RENDER_ANIMATION')
- props.animation = True
- props.sequencer = True
- layout.separator()
- layout.menu("INFO_MT_area")
- class SEQUENCER_MT_select_handle(Menu):
- bl_label = "Select Handle"
- def draw(self, _context):
- layout = self.layout
- layout.operator("sequencer.select_handles", text="Both").side = 'BOTH'
- layout.operator("sequencer.select_handles", text="Left").side = 'LEFT'
- layout.operator("sequencer.select_handles", text="Right").side = 'RIGHT'
- class SEQUENCER_MT_select_channel(Menu):
- bl_label = "Select Channel"
- def draw(self, _context):
- layout = self.layout
- layout.operator("sequencer.select_active_side", text="Left").side = 'LEFT'
- layout.operator("sequencer.select_active_side", text="Right").side = 'RIGHT'
- class SEQUENCER_MT_select_linked(Menu):
- bl_label = "Select Linked"
- def draw(self, _context):
- layout = self.layout
- layout.operator("sequencer.select_linked", text="All")
- layout.operator("sequencer.select_less", text="Less")
- layout.operator("sequencer.select_more", text="More")
- class SEQUENCER_MT_select_playhead(Menu):
- bl_label = "Select Playhead"
- def draw(self, _context):
- layout = self.layout
- props = layout.operator("sequencer.select", text="Left")
- props.left_right = 'LEFT'
- props.linked_time = True
- props = layout.operator("sequencer.select", text="Right")
- props.left_right = 'RIGHT'
- props.linked_time = True
- class SEQUENCER_MT_select(Menu):
- bl_label = "Select"
- def draw(self, _context):
- layout = self.layout
- layout.operator("sequencer.select_all", text="All").action = 'SELECT'
- layout.operator("sequencer.select_all", text="None").action = 'DESELECT'
- layout.operator("sequencer.select_all", text="Invert").action = 'INVERT'
- layout.separator()
- layout.operator("sequencer.select_box", text="Box Select")
- layout.separator()
- layout.menu("SEQUENCER_MT_select_playhead", text="Playhead")
- layout.menu("SEQUENCER_MT_select_handle", text="Handle")
- layout.menu("SEQUENCER_MT_select_channel", text="Channel")
- layout.menu("SEQUENCER_MT_select_linked", text="Linked")
- layout.separator()
- layout.operator_menu_enum("sequencer.select_grouped", "type", text="Grouped")
- class SEQUENCER_MT_marker(Menu):
- bl_label = "Marker"
- def draw(self, context):
- layout = self.layout
- st = context.space_data
- is_sequencer_view = st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}
- from bl_ui.space_time import marker_menu_generic
- marker_menu_generic(layout, context)
- if is_sequencer_view:
- layout.prop(st, "use_marker_sync")
- class SEQUENCER_MT_change(Menu):
- bl_label = "Change"
- def draw(self, context):
- layout = self.layout
- strip = act_strip(context)
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator_menu_enum("sequencer.change_effect_input", "swap")
- layout.operator_menu_enum("sequencer.change_effect_type", "type")
- prop = layout.operator("sequencer.change_path", text="Path/Files")
- if strip:
- strip_type = strip.type
- if strip_type == 'IMAGE':
- prop.filter_image = True
- elif strip_type == 'MOVIE':
- prop.filter_movie = True
- elif strip_type == 'SOUND':
- prop.filter_sound = True
- class SEQUENCER_MT_navigation(Menu):
- bl_label = "Navigation"
- def draw(self, _context):
- layout = self.layout
- layout.operator("screen.animation_play")
- layout.separator()
- layout.operator("sequencer.view_frame", text="Go to Playhead")
- layout.separator()
- props = layout.operator("sequencer.strip_jump", text="Jump to Previous Strip")
- props.next = False
- props.center = False
- props = layout.operator("sequencer.strip_jump", text="Jump to Next Strip")
- props.next = True
- props.center = False
- layout.separator()
- props = layout.operator("sequencer.strip_jump", text="Jump to Previous Strip (Center)")
- props.next = False
- props.center = True
- props = layout.operator("sequencer.strip_jump", text="Jump to Next Strip (Center)")
- props.next = True
- props.center = True
- class SEQUENCER_MT_add(Menu):
- bl_label = "Add"
- bl_translation_context = i18n_contexts.operator_default
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'INVOKE_REGION_WIN'
- bpy_data_scenes_len = len(bpy.data.scenes)
- if bpy_data_scenes_len > 10:
- layout.operator_context = 'INVOKE_DEFAULT'
- layout.operator("sequencer.scene_strip_add", text="Scene...", icon='SCENE_DATA')
- elif bpy_data_scenes_len > 1:
- layout.operator_menu_enum("sequencer.scene_strip_add", "scene", text="Scene", icon='SCENE_DATA')
- else:
- layout.menu("SEQUENCER_MT_add_empty", text="Scene", icon='SCENE_DATA')
- del bpy_data_scenes_len
- bpy_data_movieclips_len = len(bpy.data.movieclips)
- if bpy_data_movieclips_len > 10:
- layout.operator_context = 'INVOKE_DEFAULT'
- layout.operator("sequencer.movieclip_strip_add", text="Clip...", icon='TRACKER')
- elif bpy_data_movieclips_len > 0:
- layout.operator_menu_enum("sequencer.movieclip_strip_add", "clip", text="Clip", icon='TRACKER')
- else:
- layout.menu("SEQUENCER_MT_add_empty", text="Clip", icon='TRACKER')
- del bpy_data_movieclips_len
- bpy_data_masks_len = len(bpy.data.masks)
- if bpy_data_masks_len > 10:
- layout.operator_context = 'INVOKE_DEFAULT'
- layout.operator("sequencer.mask_strip_add", text="Mask...", icon='MOD_MASK')
- elif bpy_data_masks_len > 0:
- layout.operator_menu_enum("sequencer.mask_strip_add", "mask", text="Mask", icon='MOD_MASK')
- else:
- layout.menu("SEQUENCER_MT_add_empty", text="Mask", icon='MOD_MASK')
- del bpy_data_masks_len
- layout.separator()
- layout.operator("sequencer.movie_strip_add", text="Movie", icon='FILE_MOVIE')
- layout.operator("sequencer.sound_strip_add", text="Sound", icon='FILE_SOUND')
- layout.operator("sequencer.image_strip_add", text="Image/Sequence", icon='FILE_IMAGE')
- layout.separator()
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("sequencer.effect_strip_add", text="Color", icon='COLOR').type = 'COLOR'
- layout.operator("sequencer.effect_strip_add", text="Text", icon='FONT_DATA').type = 'TEXT'
- layout.separator()
- layout.operator("sequencer.effect_strip_add", text="Adjustment Layer", icon='COLOR').type = 'ADJUSTMENT'
- layout.operator_context = 'INVOKE_DEFAULT'
- layout.menu("SEQUENCER_MT_add_effect", icon='SHADERFX')
- col = layout.column()
- col.menu("SEQUENCER_MT_add_transitions", icon='ARROW_LEFTRIGHT')
- col.enabled = selected_sequences_len(context) >= 2
- class SEQUENCER_MT_add_empty(Menu):
- bl_label = "Empty"
- def draw(self, _context):
- layout = self.layout
- layout.label(text="No Items Available")
- class SEQUENCER_MT_add_transitions(Menu):
- bl_label = "Transitions"
- def draw(self, context):
- layout = self.layout
- col = layout.column()
- col.operator("sequencer.crossfade_sounds", text="Sound Crossfade")
- col.separator()
- col.operator("sequencer.effect_strip_add", text="Cross").type = 'CROSS'
- col.operator("sequencer.effect_strip_add", text="Gamma Cross").type = 'GAMMA_CROSS'
- col.separator()
- col.operator("sequencer.effect_strip_add", text="Wipe").type = 'WIPE'
- col.enabled = selected_sequences_len(context) >= 2
- class SEQUENCER_MT_add_effect(Menu):
- bl_label = "Effect Strip"
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'INVOKE_REGION_WIN'
- col = layout.column()
- col.operator("sequencer.effect_strip_add", text="Add").type = 'ADD'
- col.operator("sequencer.effect_strip_add", text="Subtract").type = 'SUBTRACT'
- col.operator("sequencer.effect_strip_add", text="Multiply").type = 'MULTIPLY'
- col.operator("sequencer.effect_strip_add", text="Over Drop").type = 'OVER_DROP'
- col.operator("sequencer.effect_strip_add", text="Alpha Over").type = 'ALPHA_OVER'
- col.operator("sequencer.effect_strip_add", text="Alpha Under").type = 'ALPHA_UNDER'
- col.operator("sequencer.effect_strip_add", text="Color Mix").type = 'COLORMIX'
- col.enabled = selected_sequences_len(context) >= 2
- layout.separator()
- layout.operator("sequencer.effect_strip_add", text="Multicam Selector").type = 'MULTICAM'
- layout.separator()
- col = layout.column()
- col.operator("sequencer.effect_strip_add", text="Transform").type = 'TRANSFORM'
- col.operator("sequencer.effect_strip_add", text="Speed Control").type = 'SPEED'
- col.separator()
- col.operator("sequencer.effect_strip_add", text="Glow").type = 'GLOW'
- col.operator("sequencer.effect_strip_add", text="Gaussian Blur").type = 'GAUSSIAN_BLUR'
- col.enabled = selected_sequences_len(context) != 0
- class SEQUENCER_MT_strip_transform(Menu):
- bl_label = "Transform"
- def draw(self, _context):
- layout = self.layout
- layout.operator("transform.seq_slide", text="Move")
- layout.operator("transform.transform", text="Move/Extend from Playhead").mode = 'TIME_EXTEND'
- layout.operator("sequencer.slip", text="Slip Strip Contents")
- layout.separator()
- layout.operator("sequencer.snap")
- layout.operator("sequencer.offset_clear")
- layout.separator()
- layout.operator_menu_enum("sequencer.swap", "side")
- layout.separator()
- layout.operator("sequencer.gap_remove").all = False
- layout.operator("sequencer.gap_insert")
- class SEQUENCER_MT_strip_input(Menu):
- bl_label = "Inputs"
- def draw(self, context):
- layout = self.layout
- strip = act_strip(context)
- layout.operator("sequencer.reload", text="Reload Strips")
- layout.operator("sequencer.reload", text="Reload Strips and Adjust Length").adjust_length = True
- prop = layout.operator("sequencer.change_path", text="Change Path/Files")
- layout.operator("sequencer.swap_data", text="Swap Data")
- if strip:
- strip_type = strip.type
- if strip_type == 'IMAGE':
- prop.filter_image = True
- elif strip_type == 'MOVIE':
- prop.filter_movie = True
- elif strip_type == 'SOUND':
- prop.filter_sound = True
- class SEQUENCER_MT_strip_lock_mute(Menu):
- bl_label = "Lock/Mute"
- def draw(self, _context):
- layout = self.layout
- layout.operator("sequencer.lock")
- layout.operator("sequencer.unlock")
- layout.separator()
- layout.operator("sequencer.mute").unselected = False
- layout.operator("sequencer.unmute").unselected = False
- layout.operator("sequencer.mute", text="Mute Unselected Strips").unselected = True
- layout.operator("sequencer.unmute", text="Unmute Deselected Strips").unselected = True
- class SEQUENCER_MT_strip_effect(Menu):
- bl_label = "Effect Strip"
- def draw(self, _context):
- layout = self.layout
- layout.operator_menu_enum("sequencer.change_effect_input", "swap")
- layout.operator_menu_enum("sequencer.change_effect_type", "type")
- layout.operator("sequencer.reassign_inputs")
- layout.operator("sequencer.swap_inputs")
- class SEQUENCER_MT_strip_movie(Menu):
- bl_label = "Movie Strip"
- def draw(self, _context):
- layout = self.layout
- layout.operator("sequencer.rendersize")
- layout.operator("sequencer.deinterlace_selected_movies")
- class SEQUENCER_MT_strip(Menu):
- bl_label = "Strip"
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.separator()
- layout.menu("SEQUENCER_MT_strip_transform")
- layout.separator()
- layout.operator("sequencer.cut", text="Cut").type = 'SOFT'
- layout.operator("sequencer.cut", text="Hold Cut").type = 'HARD'
- layout.separator()
- layout.operator("sequencer.copy", text="Copy")
- layout.operator("sequencer.paste", text="Paste")
- layout.operator("sequencer.duplicate_move")
- layout.operator("sequencer.delete", text="Delete...")
- strip = act_strip(context)
- if strip:
- strip_type = strip.type
- if strip_type != 'SOUND':
- layout.separator()
- layout.operator_menu_enum("sequencer.strip_modifier_add", "type", text="Add Modifier")
- layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
- if strip_type in {
- 'CROSS', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
- 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP', 'WIPE', 'GLOW',
- 'TRANSFORM', 'COLOR', 'SPEED', 'MULTICAM', 'ADJUSTMENT',
- 'GAUSSIAN_BLUR', 'TEXT',
- }:
- layout.separator()
- layout.menu("SEQUENCER_MT_strip_effect")
- elif strip_type == 'MOVIE':
- layout.separator()
- layout.menu("SEQUENCER_MT_strip_movie")
- elif strip_type == 'IMAGE':
- layout.separator()
- layout.operator("sequencer.rendersize")
- layout.operator("sequencer.images_separate")
- elif strip_type == 'META':
- layout.separator()
- layout.operator("sequencer.meta_make")
- layout.operator("sequencer.meta_separate")
- layout.operator("sequencer.meta_toggle", text="Toggle Meta")
- if strip_type != 'META':
- layout.separator()
- layout.operator("sequencer.meta_make")
- layout.operator("sequencer.meta_toggle", text="Toggle Meta")
- layout.separator()
- layout.menu("SEQUENCER_MT_strip_lock_mute")
- layout.separator()
- layout.menu("SEQUENCER_MT_strip_input")
- layout.separator()
- layout.operator("sequencer.rebuild_proxy")
- class SEQUENCER_MT_context_menu(Menu):
- bl_label = "Sequencer Context Menu"
- def draw(self, context):
- layout = self.layout
- layout.operator_context = 'INVOKE_REGION_WIN'
- layout.operator("sequencer.cut", text="Cut").type = 'SOFT'
- layout.separator()
- layout.operator("sequencer.copy", text="Copy", icon='COPYDOWN')
- layout.operator("sequencer.paste", text="Paste", icon='PASTEDOWN')
- layout.operator("sequencer.duplicate_move")
- layout.operator("sequencer.delete", text="Delete...")
- layout.separator()
- layout.operator("sequencer.slip", text="Slip Strip Contents")
- layout.operator("sequencer.snap")
- layout.separator()
- layout.operator("sequencer.gap_remove").all = False
- layout.operator("sequencer.gap_insert")
- strip = act_strip(context)
- if strip:
- strip_type = strip.type
- if strip_type != 'SOUND':
- layout.separator()
- layout.operator_menu_enum("sequencer.strip_modifier_add", "type", text="Add Modifier")
- layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
- if selected_sequences_len(context) >= 2:
- layout.separator()
- col = layout.column()
- col.menu("SEQUENCER_MT_add_transitions", text="Add Transition")
- elif selected_sequences_len(context) >= 2:
- layout.separator()
- layout.operator("sequencer.crossfade_sounds", text="Crossfade Sounds")
- if strip_type in {
- 'CROSS', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
- 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP', 'WIPE', 'GLOW',
- 'TRANSFORM', 'COLOR', 'SPEED', 'MULTICAM', 'ADJUSTMENT',
- 'GAUSSIAN_BLUR', 'TEXT',
- }:
- layout.separator()
- layout.menu("SEQUENCER_MT_strip_effect")
- elif strip_type in 'MOVIE':
- layout.separator()
- layout.menu("SEQUENCER_MT_strip_movie")
- elif strip_type == 'IMAGE':
- layout.separator()
- layout.operator("sequencer.rendersize")
- layout.operator("sequencer.images_separate")
- elif strip_type == 'META':
- layout.separator()
- layout.operator("sequencer.meta_make")
- layout.operator("sequencer.meta_separate")
- layout.operator("sequencer.meta_toggle", text="Toggle Meta")
- if strip_type != 'META':
- layout.separator()
- layout.operator("sequencer.meta_make")
- layout.operator("sequencer.meta_toggle", text="Toggle Meta")
- layout.separator()
- layout.menu("SEQUENCER_MT_strip_lock_mute")
- class SequencerButtonsPanel:
- bl_space_type = 'SEQUENCE_EDITOR'
- bl_region_type = 'UI'
- @staticmethod
- def has_sequencer(context):
- return (context.space_data.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'})
- @classmethod
- def poll(cls, context):
- return cls.has_sequencer(context) and (act_strip(context) is not None)
- class SequencerButtonsPanel_Output:
- bl_space_type = 'SEQUENCE_EDITOR'
- bl_region_type = 'UI'
- @staticmethod
- def has_preview(context):
- st = context.space_data
- return (st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}) or st.show_backdrop
- @classmethod
- def poll(cls, context):
- return cls.has_preview(context)
- class SEQUENCER_PT_strip(SequencerButtonsPanel, Panel):
- bl_label = ""
- bl_options = {'HIDE_HEADER'}
- bl_category = "Strip"
- def draw(self, context):
- layout = self.layout
- strip = act_strip(context)
- strip_type = strip.type
- if strip_type in {
- 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER', 'MULTIPLY',
- 'OVER_DROP', 'GLOW', 'TRANSFORM', 'SPEED', 'MULTICAM',
- 'GAUSSIAN_BLUR', 'COLORMIX',
- }:
- icon_header = 'SHADERFX'
- elif strip_type in {
- 'CROSS', 'GAMMA_CROSS', 'WIPE',
- }:
- icon_header = 'ARROW_LEFTRIGHT'
- elif strip_type == 'SCENE':
- icon_header = 'SCENE_DATA'
- elif strip_type == 'MOVIECLIP':
- icon_header = 'TRACKER'
- elif strip_type == 'MASK':
- icon_header = 'MOD_MASK'
- elif strip_type == 'MOVIE':
- icon_header = 'FILE_MOVIE'
- elif strip_type == 'SOUND':
- icon_header = 'FILE_SOUND'
- elif strip_type == 'IMAGE':
- icon_header = 'FILE_IMAGE'
- elif strip_type == 'COLOR':
- icon_header = 'COLOR'
- elif strip_type == 'TEXT':
- icon_header = 'FONT_DATA'
- elif strip_type == 'ADJUSTMENT':
- icon_header = 'COLOR'
- else:
- icon_header = 'SEQ_SEQUENCER'
- row = layout.row()
- row.label(text="", icon=icon_header)
- row.prop(strip, "name", text="")
- row.prop(strip, "mute", toggle=True, icon_only=True, emboss=False)
- class SEQUENCER_PT_adjust_transform_offset(SequencerButtonsPanel, Panel):
- bl_label = "Offset"
- bl_parent_id = "SEQUENCER_PT_adjust_transform"
- bl_options = {'DEFAULT_CLOSED'}
- bl_category = "Strip"
- @classmethod
- def poll(cls, context):
- strip = act_strip(context)
- return strip.type != 'SOUND'
- def draw_header(self, context):
- strip = act_strip(context)
- self.layout.prop(strip, "use_translation", text="")
- def draw(self, context):
- strip = act_strip(context)
- layout = self.layout
- layout.use_property_split = True
- layout.active = strip.use_translation and (not strip.mute)
- col = layout.column(align=True)
- col.prop(strip.transform, "offset_x", text="Position X")
- col.prop(strip.transform, "offset_y", text="Y")
- class SEQUENCER_PT_adjust_transform_crop(SequencerButtonsPanel, Panel):
- bl_label = "Crop"
- bl_parent_id = "SEQUENCER_PT_adjust_transform"
- bl_options = {'DEFAULT_CLOSED'}
- bl_category = "Strip"
- @classmethod
- def poll(cls, context):
- strip = act_strip(context)
- return strip.type != 'SOUND'
- def draw_header(self, context):
- strip = act_strip(context)
- self.layout.prop(strip, "use_crop", text="")
- def draw(self, context):
- strip = act_strip(context)
- layout = self.layout
- layout.use_property_split = True
- layout.active = strip.use_crop and (not strip.mute)
- col = layout.column(align=True)
- col.prop(strip.crop, "min_x")
- col.prop(strip.crop, "max_x")
- col.prop(strip.crop, "max_y")
- col.prop(strip.crop, "min_y")
- class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
- bl_label = "Effect Strip"
- bl_category = "Strip"
- @classmethod
- def poll(cls, context):
- if not cls.has_sequencer(context):
- return False
- strip = act_strip(context)
- if not strip:
- return False
- return strip.type in {
- 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
- 'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
- 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', 'SPEED',
- 'MULTICAM', 'GAUSSIAN_BLUR', 'TEXT', 'COLORMIX'
- }
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- strip = act_strip(context)
- layout.active = not strip.mute
- if strip.input_count > 0:
- col = layout.column()
- col.enabled = False
- col.prop(strip, "input_1")
- if strip.input_count > 1:
- col.prop(strip, "input_2")
- strip_type = strip.type
- if strip_type == 'COLOR':
- layout.prop(strip, "color")
- elif strip_type == 'WIPE':
- col = layout.column()
- col.prop(strip, "transition_type")
- col.alignment = 'RIGHT'
- col.row().prop(strip, "direction", expand=True)
- col = layout.column()
- col.prop(strip, "blur_width", slider=True)
- if strip.transition_type in {'SINGLE', 'DOUBLE'}:
- col.prop(strip, "angle")
- elif strip_type == 'GLOW':
- flow = layout.column_flow()
- flow.prop(strip, "threshold", slider=True)
- flow.prop(strip, "clamp", slider=True)
- flow.prop(strip, "boost_factor")
- flow.prop(strip, "blur_radius")
- row = layout.row()
- row.prop(strip, "quality", slider=True)
- row.prop(strip, "use_only_boost")
- elif strip_type == 'SPEED':
- layout.prop(strip, "use_default_fade", text="Stretch to input strip length")
- if not strip.use_default_fade:
- layout.prop(strip, "use_as_speed")
- if strip.use_as_speed:
- layout.prop(strip, "speed_factor")
- else:
- layout.prop(strip, "speed_factor", text="Frame Number")
- layout.prop(strip, "use_scale_to_length")
- elif strip_type == 'TRANSFORM':
- col = layout.column()
- col.prop(strip, "interpolation")
- col.prop(strip, "translation_unit")
- col = layout.column(align=True)
- col.prop(strip, "translate_start_x", text="Position X")
- col.prop(strip, "translate_start_y", text="Y")
- col.separator()
- colsub = col.column(align=True)
- colsub.prop(strip, "use_uniform_scale")
- if strip.use_uniform_scale:
- colsub = col.column(align=True)
- colsub.prop(strip, "scale_start_x", text="Scale")
- else:
- col.prop(strip, "scale_start_x", text="Scale X")
- col.prop(strip, "scale_start_y", text="Y")
- col.separator()
- col.prop(strip, "rotation_start", text="Rotation")
- elif strip_type == 'MULTICAM':
- col = layout.column(align=True)
- strip_channel = strip.channel
- col.prop(strip, "multicam_source", text="Source Channel")
- # The multicam strip needs at least 2 strips to be useful
- if strip_channel > 2:
- BT_ROW = 4
- col.label(text=" Cut to")
- row = col.row()
- for i in range(1, strip_channel):
- if (i % BT_ROW) == 1:
- row = col.row(align=True)
- # Workaround - .enabled has to have a separate UI block to work
- if i == strip.multicam_source:
- sub = row.row(align=True)
- sub.enabled = False
- sub.operator("sequencer.cut_multicam", text=f"{i:d}").camera = i
- else:
- sub_1 = row.row(align=True)
- sub_1.enabled = True
- sub_1.operator("sequencer.cut_multicam", text=f"{i:d}").camera = i
- if strip.channel > BT_ROW and (strip_channel - 1) % BT_ROW:
- for i in range(strip.channel, strip_channel + ((BT_ROW + 1 - strip_channel) % BT_ROW)):
- row.label(text="")
- else:
- col.separator()
- col.label(text="Two or more channels are needed below this strip", icon='INFO')
- elif strip_type == 'TEXT':
- col = layout.column()
- col.prop(strip, "text")
- col.template_ID(strip, "font", open="font.open", unlink="font.unlink")
- col.prop(strip, "font_size")
- row = col.row()
- row.prop(strip, "color")
- row = col.row()
- row.prop(strip, "use_shadow")
- rowsub = row.row()
- rowsub.active = strip.use_shadow
- rowsub.prop(strip, "shadow_color", text="")
- col.prop(strip, "align_x", text="Horizontal")
- col.prop(strip, "align_y", text="Vertical")
- row = col.row(align=True)
- row.prop(strip, "location", text="Location", slider=True)
- col.prop(strip, "wrap_width")
- layout.operator("sequencer.export_subtitles", text="Export Subtitles", icon='EXPORT')
- col = layout.column(align=True)
- if strip_type == 'SPEED':
- col.prop(strip, "multiply_speed")
- elif strip_type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}:
- col.prop(strip, "use_default_fade", text="Default fade")
- if not strip.use_default_fade:
- col.prop(strip, "effect_fader", text="Effect Fader")
- elif strip_type == 'GAUSSIAN_BLUR':
- col = layout.column(align=True)
- col.prop(strip, "size_x", text="Size X")
- col.prop(strip, "size_y", text="Y")
- elif strip_type == 'COLORMIX':
- layout.prop(strip, "blend_effect", text="Blend Mode")
- row = layout.row(align=True)
- row.prop(strip, "factor", slider=True)
- class SEQUENCER_PT_source(SequencerButtonsPanel, Panel):
- bl_label = "Source"
- bl_options = {'DEFAULT_CLOSED'}
- bl_category = "Strip"
- @classmethod
- def poll(cls, context):
- if not cls.has_sequencer(context):
- return False
- strip = act_strip(context)
- if not strip:
- return False
- return strip.type in {'MOVIE', 'IMAGE', 'SOUND'}
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
- scene = context.scene
- strip = act_strip(context)
- strip_type = strip.type
- layout.active = not strip.mute
- # Draw a filename if we have one.
- if strip_type == 'SOUND':
- sound = strip.sound
- layout.template_ID(strip, "sound", open="sound.open")
- if sound is not None:
- col = layout.column()
- col.prop(sound, "filepath", text="")
- col.alignment = 'RIGHT'
- sub = col.column(align=True)
- split = sub.split(factor=0.5, align=True)
- split.alignment = 'RIGHT'
- if sound.packed_file:
- split.label(text="Unpack")
- split.operator("sound.unpack", icon='PACKAGE', text="")
- else:
- split.label(text="Pack")
- split.operator("sound.pack", icon='UGLYPACKAGE', text="")
- layout.prop(sound, "use_memory_cache")
- else:
- if strip_type == 'IMAGE':
- col = layout.column()
- col.prop(strip, "directory", text="")
- # Current element for the filename.
- elem = strip.strip_elem_from_frame(scene.frame_current)
- if elem:
- col.prop(elem, "filename", text="") # strip.elements[0] could be a fallback
- col.prop(strip.colorspace_settings, "name", text="Color Space")
- col.prop(strip, "alpha_mode", text="Alpha")
- sub = col.column(align=True)
- sub.operator("sequencer.change_path", text="Change Data/Files", icon='FILEBROWSER').filter_image = True
- else: # elif strip_type == 'MOVIE':
- elem = strip.elements[0]
- col = layout.column()
- col.prop(strip, "filepath", text="")
- col.prop(strip.colorspace_settings, "name", text="Color Space")
- col.prop(strip, "mpeg_preseek")
- col.prop(strip, "stream_index")
- col.prop(strip, "use_deinterlace")
- if scene.render.use_multiview:
- layout.prop(strip, "use_multiview")
- col = layout.column()
- col.active = strip.use_multiview
- col.row().prop(strip, "views_format", expand=True)
- box = col.box()
- box.active = strip.views_format == 'STEREO_3D'
- box.template_image_stereo_3d(strip.stereo_3d_format)
- # Resolution.
- col = layout.column(align=True)
- col = col.box()
- split = col.split(factor=0.5, align=False)
- split.alignment = 'RIGHT'
- split.label(text="Resolution")
- size = (elem.orig_width, elem.orig_height) if elem else (0, 0)
- if size[0] and size[1]:
- split.alignment = 'LEFT'
- split.label(text="%dx%d" % size, translate=False)
- else:
- split.label(text="None")
- class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel):
- bl_label = "Sound"
- bl_parent_id = ""
- bl_category = "Strip"
- @classmethod
- def poll(cls, context):
- if not cls.has_sequencer(context):
- return False
- strip = act_strip(context)
- if not strip:
- return False
- return (strip.type == 'SOUND')
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- strip = act_strip(context)
- sound = strip.sound
- layout.active = not strip.mute
- layout.template_ID(strip, "sound", open="sound.open")
- if sound is not None:
- layout.prop(sound, "filepath", text="")
- layout.use_property_split = True
- layout.use_property_decorate = False
- layout.alignment = 'RIGHT'
- sub = layout.column(align=True)
- split = sub.split(factor=0.5, align=True)
- split.alignment = 'RIGHT'
- if sound.packed_file:
- split.label(text="Unpack")
- split.operator("sound.unpack", icon='PACKAGE', text="")
- else:
- split.label(text="Pack")
- split.operator("sound.pack", icon='UGLYPACKAGE', text="")
- layout.prop(sound, "use_memory_cache")
- class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel):
- bl_label = "Scene"
- bl_category = "Strip"
- @classmethod
- def poll(cls, context):
- if not cls.has_sequencer(context):
- return False
- strip = act_strip(context)
- if not strip:
- return False
- return (strip.type == 'SCENE')
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
- strip = act_strip(context)
- layout.active = not strip.mute
- layout.template_ID(strip, "scene")
- scene = strip.scene
- layout.prop(strip, "scene_input")
- if scene:
- layout.prop(scene, "audio_volume", text="Volume")
- if strip.scene_input == 'CAMERA':
- layout.alignment = 'RIGHT'
- sub = layout.column(align=True)
- split = sub.split(factor=0.5, align=True)
- split.alignment = 'RIGHT'
- split.label(text="Camera")
- split.template_ID(strip, "scene_camera")
- layout.prop(strip, "use_grease_pencil", text="Show Grease Pencil")
- if scene:
- # Warning, this is not a good convention to follow.
- # Expose here because setting the alpha from the 'Render' menu is very inconvenient.
- # layout.label(text="Preview")
- layout.prop(scene.render, "film_transparent")
- class SEQUENCER_PT_mask(SequencerButtonsPanel, Panel):
- bl_label = "Mask"
- bl_category = "Strip"
- @classmethod
- def poll(cls, context):
- if not cls.has_sequencer(context):
- return False
- strip = act_strip(context)
- if not strip:
- return False
- return (strip.type == 'MASK')
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- strip = act_strip(context)
- layout.active = not strip.mute
- layout.template_ID(strip, "mask")
- mask = strip.mask
- if mask:
- sta = mask.frame_start
- end = mask.frame_end
- layout.label(text=iface_("Original frame range: %d-%d (%d)") % (sta, end, end - sta + 1), translate=False)
- class SEQUENCER_PT_time(SequencerButtonsPanel, Panel):
- bl_label = "Time"
- bl_options = {'DEFAULT_CLOSED'}
- bl_category = "Strip"
- @classmethod
- def poll(cls, context):
- if not cls.has_sequencer(context):
- return False
- strip = act_strip(context)
- if not strip:
- return False
- return strip.type
- def draw_header_preset(self, context):
- layout = self.layout
- layout.alignment = 'RIGHT'
- strip = act_strip(context)
- layout.prop(strip, "lock", text="", icon_only=True, emboss=False)
- def draw(self, context):
- from bpy.utils import smpte_from_frame
- layout = self.layout
- layout.use_property_split = False
- layout.use_property_decorate = False
- scene = context.scene
- frame_current = scene.frame_current
- strip = act_strip(context)
- is_effect = isinstance(strip, bpy.types.EffectSequence)
- # Get once.
- frame_start = strip.frame_start
- frame_final_start = strip.frame_final_start
- frame_final_end = strip.frame_final_end
- frame_final_duration = strip.frame_final_duration
- frame_offset_start = strip.frame_offset_start
- frame_offset_end = strip.frame_offset_end
- length_list = (
- str(frame_start),
- str(frame_final_end),
- str(frame_final_duration),
- str(frame_offset_start),
- str(frame_offset_end),
- )
- if not is_effect:
- length_list = length_list + (
- str(strip.animation_offset_start),
- str(strip.animation_offset_end),
- )
- max_length = max(len(x) for x in length_list)
- max_factor = (1.9 - max_length) / 30
- layout.enabled = not strip.lock
- layout.active = not strip.mute
- sub = layout.row(align=True)
- split = sub.split(factor=0.5 + max_factor)
- split.alignment = 'RIGHT'
- split.label(text="Channel")
- split.prop(strip, "channel", text="")
- sub = layout.column(align=True)
- split = sub.split(factor=0.5 + max_factor, align=True)
- split.alignment = 'RIGHT'
- split.label(text="Start")
- split.prop(strip, "frame_start", text=smpte_from_frame(frame_start))
- split = sub.split(factor=0.5 + max_factor, align=True)
- split.alignment = 'RIGHT'
- split.label(text="Duration")
- split.prop(strip, "frame_final_duration", text=smpte_from_frame(frame_final_duration))
- # Use label, editing this value from the UI allows negative values,
- # users can adjust duration.
- split = sub.split(factor=0.5 + max_factor, align=True)
- split.alignment = 'RIGHT'
- split.label(text="End")
- split = split.split(factor=0.8 + max_factor, align=True)
- split.label(text="{:>14}".format(smpte_from_frame(frame_final_end) + ":"))
- split.alignment = 'RIGHT'
- split.label(text=str(frame_final_end) + " ")
- if not is_effect:
- layout.alignment = 'RIGHT'
- sub = layout.column(align=True)
- split = sub.split(factor=0.5 + max_factor, align=True)
- split.alignment = 'RIGHT'
- split.label(text="Strip Offset Start")
- split.prop(strip, "frame_offset_start", text=smpte_from_frame(frame_offset_start))
- split = sub.split(factor=0.5 + max_factor, align=True)
- split.alignment = 'RIGHT'
- split.label(text="End")
- split.prop(strip, "frame_offset_end", text=smpte_from_frame(frame_offset_end))
- layout.alignment = 'RIGHT'
- sub = layout.column(align=True)
- split = sub.split(factor=0.5 + max_factor, align=True)
- split.alignment = 'RIGHT'
- split.label(text="Hold Offset Start")
- split.prop(strip, "animation_offset_start", text=smpte_from_frame(strip.animation_offset_start))
- split = sub.split(factor=0.5 + max_factor, align=True)
- split.alignment = 'RIGHT'
- split.label(text="End")
- split.prop(strip, "animation_offset_end", text=smpte_from_frame(strip.animation_offset_end))
- col = layout.column(align=True)
- col = col.box()
- col.active = (
- (frame_current >= frame_final_start) and
- (frame_current <= frame_final_start + frame_final_duration)
- )
- split = col.split(factor=0.5 + max_factor, align=True)
- split.alignment = 'RIGHT'
- split.label(text="Playhead")
- split = split.split(factor=0.8 + max_factor, align=True)
- playhead = frame_current - frame_final_start
- split.label(text="{:>14}".format(smpte_from_frame(playhead) + ":"))
- split.alignment = 'RIGHT'
- split.label(text=str(playhead) + " ")
- if strip.type == 'SCENE':
- scene = strip.scene
- if scene:
- sta = scene.frame_start
- end = scene.frame_end
- split = col.split(factor=0.5 + max_factor)
- split.alignment = 'RIGHT'
- split.label(text="Original Frame Range")
- split.alignment = 'LEFT'
- split.label(text="%d-%d (%d)" % (sta, end, end - sta + 1), translate=False)
- class SEQUENCER_PT_adjust(SequencerButtonsPanel, Panel):
- bl_label = "Adjust"
- bl_category = "Strip"
- def draw(self, context):
- pass
- class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel):
- bl_label = "Sound"
- bl_parent_id = "SEQUENCER_PT_adjust"
- bl_category = "Strip"
- @classmethod
- def poll(cls, context):
- strip = act_strip(context)
- return strip.type == 'SOUND'
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- st = context.space_data
- strip = act_strip(context)
- sound = strip.sound
- layout.active = not strip.mute
- col = layout.column()
- col.prop(strip, "volume", text="Volume")
- col.prop(strip, "pitch")
- col.prop(strip, "pan")
- if sound is not None:
- if st.waveform_display_type == 'DEFAULT_WAVEFORMS':
- col.prop(strip, "show_waveform")
- col.prop(sound, "use_mono")
- class SEQUENCER_PT_adjust_comp(SequencerButtonsPanel, Panel):
- bl_label = "Compositing"
- bl_parent_id = "SEQUENCER_PT_adjust"
- bl_category = "Strip"
- @classmethod
- def poll(cls, context):
- strip = act_strip(context)
- return strip.type != 'SOUND'
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- strip = act_strip(context)
- layout.active = not strip.mute
- col = layout.column()
- col.prop(strip, "blend_type", text="Blend")
- col.prop(strip, "blend_alpha", text="Opacity", slider=True)
- class SEQUENCER_PT_adjust_transform(SequencerButtonsPanel, Panel):
- bl_label = "Transform"
- bl_parent_id = "SEQUENCER_PT_adjust"
- bl_category = "Strip"
- @classmethod
- def poll(cls, context):
- if not cls.has_sequencer(context):
- return False
- strip = act_strip(context)
- if not strip:
- return False
- return strip.type in {
- 'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'MASK',
- 'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER',
- 'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY',
- 'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
- 'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX'
- }
- def draw(self, context):
- layout = self.layout
- strip = act_strip(context)
- layout.active = not strip.mute
- split = layout.split()
- col = split.column()
- col.alignment = 'RIGHT'
- col.label(text="Mirror")
- col = split.column()
- row = col.row(align=True)
- row.prop(strip, "use_flip_x", text="X", toggle=True)
- row.prop(strip, "use_flip_y", text="Y", toggle=True)
- class SEQUENCER_PT_adjust_video(SequencerButtonsPanel, Panel):
- bl_label = "Video"
- bl_parent_id = "SEQUENCER_PT_adjust"
- bl_options = {'DEFAULT_CLOSED'}
- bl_category = "Strip"
- @classmethod
- def poll(cls, context):
- if not cls.has_sequencer(context):
- return False
- strip = act_strip(context)
- if not strip:
- return False
- return strip.type in {
- 'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'MASK',
- 'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER',
- 'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY',
- 'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
- 'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX'
- }
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- col = layout.column()
- strip = act_strip(context)
- layout.active = not strip.mute
- col.prop(strip, "strobe")
- if strip.type == 'MOVIECLIP':
- col = layout.column()
- col.label(text="Tracker")
- col.prop(strip, "stabilize2d")
- col = layout.column()
- col.label(text="Distortion")
- col.prop(strip, "undistort")
- col.separator()
- col.prop(strip, "playback_direction")
- class SEQUENCER_PT_adjust_color(SequencerButtonsPanel, Panel):
- bl_label = "Color"
- bl_parent_id = "SEQUENCER_PT_adjust"
- bl_options = {'DEFAULT_CLOSED'}
- bl_category = "Strip"
- @classmethod
- def poll(cls, context):
- if not cls.has_sequencer(context):
- return False
- strip = act_strip(context)
- if not strip:
- return False
- return strip.type in {
- 'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'MASK',
- 'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER',
- 'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY',
- 'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
- 'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX'
- }
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- strip = act_strip(context)
- layout.active = not strip.mute
- col = layout.column()
- col.prop(strip, "color_saturation", text="Saturation")
- col.prop(strip, "color_multiply", text="Multiply")
- col.prop(strip, "use_float", text="Convert to Float")
- class SEQUENCER_PT_cache_settings(SequencerButtonsPanel, Panel):
- bl_label = "Cache Settings"
- bl_category = "Proxy & Cache"
- @classmethod
- def poll(cls, context):
- return cls.has_sequencer(context) and context.scene.sequence_editor
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
- ed = context.scene.sequence_editor
- col = layout.column()
- col.prop(ed, "use_cache_raw")
- col.prop(ed, "use_cache_preprocessed")
- col.prop(ed, "use_cache_composite")
- col.prop(ed, "use_cache_final")
- col.separator()
- col.prop(ed, "recycle_max_cost")
- class SEQUENCER_PT_proxy_settings(SequencerButtonsPanel, Panel):
- bl_label = "Proxy Settings"
- bl_category = "Proxy & Cache"
- @classmethod
- def poll(cls, context):
- return cls.has_sequencer(context) and context.scene.sequence_editor
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
- ed = context.scene.sequence_editor
- flow = layout.column_flow()
- flow.prop(ed, "proxy_storage", text="Storage")
- if ed.proxy_storage == 'PROJECT':
- flow.prop(ed, "proxy_dir", text="Directory")
- col = layout.column()
- col.operator("sequencer.enable_proxies")
- col.operator("sequencer.rebuild_proxy")
- class SEQUENCER_PT_strip_proxy(SequencerButtonsPanel, Panel):
- bl_label = "Strip Proxy & Timecode"
- bl_category = "Proxy & Cache"
- @classmethod
- def poll(cls, context):
- if not cls.has_sequencer(context) and context.scene.sequence_editor:
- return False
- strip = act_strip(context)
- if not strip:
- return False
- return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'META', 'MULTICAM'}
- def draw_header(self, context):
- strip = act_strip(context)
- self.layout.prop(strip, "use_proxy", text="")
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
- ed = context.scene.sequence_editor
- strip = act_strip(context)
- if strip.proxy:
- proxy = strip.proxy
- flow = layout.column_flow()
- if ed.proxy_storage == 'PER_STRIP':
- flow.prop(proxy, "use_proxy_custom_directory")
- flow.prop(proxy, "use_proxy_custom_file")
- if proxy.use_proxy_custom_directory and not proxy.use_proxy_custom_file:
- flow.prop(proxy, "directory")
- if proxy.use_proxy_custom_file:
- flow.prop(proxy, "filepath")
- box = layout.box()
- row = box.row(align=True)
- row.prop(strip.proxy, "build_25")
- row.prop(strip.proxy, "build_75")
- row = box.row(align=True)
- row.prop(strip.proxy, "build_50")
- row.prop(strip.proxy, "build_100")
- layout.use_property_split = True
- layout.use_property_decorate = False
- layout.prop(proxy, "use_overwrite")
- col = layout.column()
- col.prop(proxy, "quality", text="Build JPEG Quality")
- if strip.type == 'MOVIE':
- col = layout.column()
- col.prop(proxy, "timecode", text="Timecode Index")
- class SEQUENCER_PT_strip_cache(SequencerButtonsPanel, Panel):
- bl_label = "Strip Cache"
- bl_category = "Proxy & Cache"
- bl_options = {'DEFAULT_CLOSED'}
- @classmethod
- def poll(cls, context):
- if not cls.has_sequencer(context):
- return False
- if act_strip(context) is not None:
- return True
- return False
- def draw_header(self, context):
- strip = act_strip(context)
- self.layout.prop(strip, "override_cache_settings", text="")
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
- strip = act_strip(context)
- layout.active = strip.override_cache_settings
- col = layout.column()
- col.prop(strip, "use_cache_raw")
- col.prop(strip, "use_cache_preprocessed")
- col.prop(strip, "use_cache_composite")
- class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, Panel):
- bl_label = "Scene Preview/Render"
- bl_space_type = 'SEQUENCE_EDITOR'
- bl_region_type = 'UI'
- bl_options = {'DEFAULT_CLOSED'}
- bl_category = "View"
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
- render = context.scene.render
- col = layout.column()
- col.prop(render, "sequencer_gl_preview", text="Preview Shading")
- if render.sequencer_gl_preview in ['SOLID', 'WIREFRAME']:
- col.prop(render, "use_sequencer_override_scene_strip")
- class SEQUENCER_PT_view(SequencerButtonsPanel_Output, Panel):
- bl_label = "View Settings"
- bl_category = "View"
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
- st = context.space_data
- col = layout.column()
- col.prop(st, "display_channel", text="Channel")
- if st.display_mode == 'IMAGE':
- col.prop(st, "show_overexposed")
- elif st.display_mode == 'WAVEFORM':
- col.prop(st, "show_separate_color")
- col.prop(st, "proxy_render_size")
- class SEQUENCER_PT_frame_overlay(SequencerButtonsPanel_Output, Panel):
- bl_label = "Frame Overlay"
- bl_category = "View"
- bl_options = {'DEFAULT_CLOSED'}
- def draw_header(self, context):
- scene = context.scene
- ed = scene.sequence_editor
- self.layout.prop(ed, "show_overlay", text="")
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
- st = context.space_data
- scene = context.scene
- ed = scene.sequence_editor
- layout.active = ed.show_overlay
- col = layout.column()
- col.prop(ed, "overlay_frame", text="Frame Offset")
- col.prop(st, "overlay_type")
- col.prop(ed, "use_overlay_lock")
- class SEQUENCER_PT_view_safe_areas(SequencerButtonsPanel_Output, Panel):
- bl_label = "Safe Areas"
- bl_options = {'DEFAULT_CLOSED'}
- bl_category = "View"
- @classmethod
- def poll(cls, context):
- st = context.space_data
- is_preview = st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}
- return is_preview and (st.display_mode == 'IMAGE')
- def draw_header(self, context):
- st = context.space_data
- self.layout.prop(st, "show_safe_areas", text="")
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- st = context.space_data
- safe_data = context.scene.safe_areas
- layout.active = st.show_safe_areas
- col = layout.column()
- sub = col.column()
- sub.prop(safe_data, "title", slider=True)
- sub.prop(safe_data, "action", slider=True)
- class SEQUENCER_PT_view_safe_areas_center_cut(SequencerButtonsPanel_Output, Panel):
- bl_label = "Center-Cut Safe Areas"
- bl_parent_id = "SEQUENCER_PT_view_safe_areas"
- bl_options = {'DEFAULT_CLOSED'}
- bl_category = "View"
- def draw_header(self, context):
- st = context.space_data
- layout = self.layout
- layout.active = st.show_safe_areas
- layout.prop(st, "show_safe_center", text="")
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- safe_data = context.scene.safe_areas
- st = context.space_data
- layout.active = st.show_safe_areas and st.show_safe_center
- col = layout.column()
- col.prop(safe_data, "title_center", slider=True)
- class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel):
- bl_label = "Modifiers"
- bl_category = "Modifiers"
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- strip = act_strip(context)
- ed = context.scene.sequence_editor
- layout.prop(strip, "use_linear_modifiers")
- layout.operator_menu_enum("sequencer.strip_modifier_add", "type")
- layout.operator("sequencer.strip_modifier_copy")
- for mod in strip.modifiers:
- box = layout.box()
- row = box.row()
- row.prop(mod, "show_expanded", text="", emboss=False)
- row.prop(mod, "name", text="")
- row.prop(mod, "mute", text="")
- sub = row.row(align=True)
- props = sub.operator("sequencer.strip_modifier_move", text="", icon='TRIA_UP')
- props.name = mod.name
- props.direction = 'UP'
- props = sub.operator("sequencer.strip_modifier_move", text="", icon='TRIA_DOWN')
- props.name = mod.name
- props.direction = 'DOWN'
- row.operator("sequencer.strip_modifier_remove", text="", icon='X', emboss=False).name = mod.name
- if mod.show_expanded:
- row = box.row()
- row.prop(mod, "input_mask_type", expand=True)
- if mod.input_mask_type == 'STRIP':
- sequences_object = ed
- if ed.meta_stack:
- sequences_object = ed.meta_stack[-1]
- box.prop_search(mod, "input_mask_strip", sequences_object, "sequences", text="Mask")
- else:
- box.prop(mod, "input_mask_id")
- row = box.row()
- row.prop(mod, "mask_time", expand=True)
- if mod.type == 'COLOR_BALANCE':
- box.prop(mod, "color_multiply")
- draw_color_balance(box, mod.color_balance)
- elif mod.type == 'CURVES':
- box.template_curve_mapping(mod, "curve_mapping", type='COLOR', show_tone=True)
- elif mod.type == 'HUE_CORRECT':
- box.template_curve_mapping(mod, "curve_mapping", type='HUE')
- elif mod.type == 'BRIGHT_CONTRAST':
- col = box.column()
- col.prop(mod, "bright")
- col.prop(mod, "contrast")
- elif mod.type == 'WHITE_BALANCE':
- col = box.column()
- col.prop(mod, "white_value")
- elif mod.type == 'TONEMAP':
- col = box.column()
- col.prop(mod, "tonemap_type")
- if mod.tonemap_type == 'RD_PHOTORECEPTOR':
- col.prop(mod, "intensity")
- col.prop(mod, "contrast")
- col.prop(mod, "adaptation")
- col.prop(mod, "correction")
- elif mod.tonemap_type == 'RH_SIMPLE':
- col.prop(mod, "key")
- col.prop(mod, "offset")
- col.prop(mod, "gamma")
- class SEQUENCER_PT_grease_pencil(AnnotationDataPanel, SequencerButtonsPanel_Output, Panel):
- bl_space_type = 'SEQUENCE_EDITOR'
- bl_region_type = 'UI'
- bl_category = "View"
- # NOTE: this is just a wrapper around the generic GP Panel
- # But, it should only show up when there are images in the preview region
- class SEQUENCER_PT_grease_pencil_tools(GreasePencilToolsPanel, SequencerButtonsPanel_Output, Panel):
- bl_space_type = 'SEQUENCE_EDITOR'
- bl_region_type = 'UI'
- bl_category = "View"
- # NOTE: this is just a wrapper around the generic GP tools panel
- # It contains access to some essential tools usually found only in
- # toolbar, which doesn't exist here...
- class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel):
- COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
- _context_path = "scene.sequence_editor.active_strip"
- _property_type = (bpy.types.Sequence,)
- bl_category = "Strip"
- classes = (
- SEQUENCER_MT_change,
- SEQUENCER_HT_header,
- SEQUENCER_MT_editor_menus,
- SEQUENCER_MT_range,
- SEQUENCER_MT_view,
- SEQUENCER_MT_view_cache,
- SEQUENCER_MT_view_toggle,
- SEQUENCER_MT_select_playhead,
- SEQUENCER_MT_select_handle,
- SEQUENCER_MT_select_channel,
- SEQUENCER_MT_select_linked,
- SEQUENCER_MT_select,
- SEQUENCER_MT_marker,
- SEQUENCER_MT_navigation,
- SEQUENCER_MT_add,
- SEQUENCER_MT_add_effect,
- SEQUENCER_MT_add_transitions,
- SEQUENCER_MT_add_empty,
- SEQUENCER_MT_strip_effect,
- SEQUENCER_MT_strip_movie,
- SEQUENCER_MT_strip,
- SEQUENCER_MT_strip_transform,
- SEQUENCER_MT_strip_input,
- SEQUENCER_MT_strip_lock_mute,
- SEQUENCER_MT_context_menu,
- SEQUENCER_PT_strip,
- SEQUENCER_PT_adjust,
- SEQUENCER_PT_adjust_comp,
- SEQUENCER_PT_adjust_transform,
- SEQUENCER_PT_adjust_transform_offset,
- SEQUENCER_PT_adjust_transform_crop,
- SEQUENCER_PT_adjust_video,
- SEQUENCER_PT_adjust_color,
- SEQUENCER_PT_adjust_sound,
- SEQUENCER_PT_effect,
- SEQUENCER_PT_scene,
- SEQUENCER_PT_mask,
- SEQUENCER_PT_time,
- SEQUENCER_PT_source,
- SEQUENCER_PT_modifiers,
- SEQUENCER_PT_cache_settings,
- SEQUENCER_PT_strip_cache,
- SEQUENCER_PT_proxy_settings,
- SEQUENCER_PT_strip_proxy,
- SEQUENCER_PT_custom_props,
- SEQUENCER_PT_preview,
- SEQUENCER_PT_view,
- SEQUENCER_PT_frame_overlay,
- SEQUENCER_PT_view_safe_areas,
- SEQUENCER_PT_view_safe_areas_center_cut,
- SEQUENCER_PT_grease_pencil,
- SEQUENCER_PT_grease_pencil_tools,
- )
- if __name__ == "__main__": # only for live edit.
- from bpy.utils import register_class
- for cls in classes:
- register_class(cls)
|