space_sequencer.py 67 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090
  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. # <pep8 compliant>
  19. import bpy
  20. from bpy.types import (
  21. Header,
  22. Menu,
  23. Panel,
  24. )
  25. from bpy.app.translations import (
  26. contexts as i18n_contexts,
  27. pgettext_iface as iface_,
  28. )
  29. from bl_ui.properties_grease_pencil_common import (
  30. AnnotationDataPanel,
  31. GreasePencilToolsPanel,
  32. )
  33. from rna_prop_ui import PropertyPanel
  34. def act_strip(context):
  35. try:
  36. return context.scene.sequence_editor.active_strip
  37. except AttributeError:
  38. return None
  39. def selected_sequences_len(context):
  40. selected_sequences = getattr(context, "selected_sequences", None)
  41. if selected_sequences is None:
  42. return 0
  43. return len(selected_sequences)
  44. def draw_color_balance(layout, color_balance):
  45. layout.use_property_split = False
  46. flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
  47. col = flow.column()
  48. box = col.box()
  49. split = box.split(factor=0.35)
  50. col = split.column(align=True)
  51. col.label(text="Lift:")
  52. col.separator()
  53. col.separator()
  54. col.prop(color_balance, "lift", text="")
  55. col.prop(color_balance, "invert_lift", text="Invert", icon='ARROW_LEFTRIGHT')
  56. split.template_color_picker(color_balance, "lift", value_slider=True, cubic=True)
  57. col = flow.column()
  58. box = col.box()
  59. split = box.split(factor=0.35)
  60. col = split.column(align=True)
  61. col.label(text="Gamma:")
  62. col.separator()
  63. col.separator()
  64. col.prop(color_balance, "gamma", text="")
  65. col.prop(color_balance, "invert_gamma", text="Invert", icon='ARROW_LEFTRIGHT')
  66. split.template_color_picker(color_balance, "gamma", value_slider=True, lock_luminosity=True, cubic=True)
  67. col = flow.column()
  68. box = col.box()
  69. split = box.split(factor=0.35)
  70. col = split.column(align=True)
  71. col.label(text="Gain:")
  72. col.separator()
  73. col.separator()
  74. col.prop(color_balance, "gain", text="")
  75. col.prop(color_balance, "invert_gain", text="Invert", icon='ARROW_LEFTRIGHT')
  76. split.template_color_picker(color_balance, "gain", value_slider=True, lock_luminosity=True, cubic=True)
  77. class SEQUENCER_HT_header(Header):
  78. bl_space_type = 'SEQUENCE_EDITOR'
  79. def draw(self, context):
  80. layout = self.layout
  81. st = context.space_data
  82. layout.template_header()
  83. layout.prop(st, "view_type", text="")
  84. SEQUENCER_MT_editor_menus.draw_collapsible(context, layout)
  85. layout.separator_spacer()
  86. if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
  87. layout.prop(st, "display_mode", text="", icon_only=True)
  88. if st.view_type != 'SEQUENCER':
  89. layout.prop(st, "preview_channels", text="", icon_only=True)
  90. if st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}:
  91. gpd = context.gpencil_data
  92. tool_settings = context.tool_settings
  93. # Proportional editing
  94. if gpd and gpd.use_stroke_edit_mode:
  95. row = layout.row(align=True)
  96. row.prop(tool_settings, "use_proportional_edit", icon_only=True)
  97. if tool_settings.use_proportional_edit:
  98. row.prop(tool_settings, "proportional_edit_falloff", icon_only=True)
  99. class SEQUENCER_MT_editor_menus(Menu):
  100. bl_idname = "SEQUENCER_MT_editor_menus"
  101. bl_label = ""
  102. def draw(self, context):
  103. layout = self.layout
  104. st = context.space_data
  105. layout.menu("SEQUENCER_MT_view")
  106. if st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}:
  107. layout.menu("SEQUENCER_MT_select")
  108. layout.menu("SEQUENCER_MT_marker")
  109. layout.menu("SEQUENCER_MT_add")
  110. layout.menu("SEQUENCER_MT_strip")
  111. class SEQUENCER_MT_view_toggle(Menu):
  112. bl_label = "View Type"
  113. def draw(self, _context):
  114. layout = self.layout
  115. layout.operator("sequencer.view_toggle").type = 'SEQUENCER'
  116. layout.operator("sequencer.view_toggle").type = 'PREVIEW'
  117. layout.operator("sequencer.view_toggle").type = 'SEQUENCER_PREVIEW'
  118. class SEQUENCER_MT_view_cache(Menu):
  119. bl_label = "Cache"
  120. def draw(self, context):
  121. layout = self.layout
  122. ed = context.scene.sequence_editor
  123. layout.prop(ed, "show_cache")
  124. layout.separator()
  125. col = layout.column()
  126. col.enabled = ed.show_cache
  127. col.prop(ed, "show_cache_final_out")
  128. col.prop(ed, "show_cache_raw")
  129. col.prop(ed, "show_cache_preprocessed")
  130. col.prop(ed, "show_cache_composite")
  131. class SEQUENCER_MT_range(Menu):
  132. bl_label = "Range"
  133. def draw(self, _context):
  134. layout = self.layout
  135. layout.operator("anim.previewrange_set", text="Set Preview Range")
  136. layout.operator("anim.previewrange_clear", text="Clear Preview Range")
  137. layout.separator()
  138. layout.operator("anim.start_frame_set", text="Set Start Frame")
  139. layout.operator("anim.end_frame_set", text="Set End Frame")
  140. class SEQUENCER_MT_view(Menu):
  141. bl_label = "View"
  142. def draw(self, context):
  143. layout = self.layout
  144. st = context.space_data
  145. is_preview = st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}
  146. is_sequencer_view = st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}
  147. if st.view_type == 'PREVIEW':
  148. # Specifying the REGION_PREVIEW context is needed in preview-only
  149. # mode, else the lookup for the shortcut will fail in
  150. # wm_keymap_item_find_props() (see #32595).
  151. layout.operator_context = 'INVOKE_REGION_PREVIEW'
  152. layout.prop(st, "show_region_ui")
  153. layout.operator_context = 'INVOKE_DEFAULT'
  154. if st.view_type == 'SEQUENCER':
  155. layout.prop(st, "show_backdrop", text="Preview as Backdrop")
  156. layout.separator()
  157. if is_sequencer_view:
  158. layout.operator_context = 'INVOKE_REGION_WIN'
  159. layout.operator("sequencer.view_selected", text="Frame Selected")
  160. layout.operator("sequencer.view_all", text="Frame All")
  161. layout.operator("view2d.zoom_border", text="Zoom")
  162. layout.separator()
  163. layout.operator_context = 'INVOKE_DEFAULT'
  164. layout.menu("SEQUENCER_MT_navigation")
  165. layout.menu("SEQUENCER_MT_range")
  166. layout.separator()
  167. layout.operator_context = 'INVOKE_REGION_WIN'
  168. layout.operator("sequencer.refresh_all", icon='FILE_REFRESH', text="Refresh All")
  169. layout.separator()
  170. layout.operator_context = 'INVOKE_DEFAULT'
  171. if is_preview:
  172. layout.operator_context = 'INVOKE_REGION_PREVIEW'
  173. layout.operator("sequencer.view_all_preview", text="Fit Preview in window")
  174. layout.operator("view2d.zoom_border", text="Zoom")
  175. layout.separator()
  176. ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
  177. for a, b in ratios:
  178. layout.operator(
  179. "sequencer.view_zoom_ratio",
  180. text=iface_("Zoom %d:%d") % (a, b),
  181. translate=False,
  182. ).ratio = a / b
  183. layout.separator()
  184. layout.operator_context = 'INVOKE_DEFAULT'
  185. # # XXX, invokes in the header view
  186. # layout.operator("sequencer.view_ghost_border", text="Overlay Border")
  187. if is_sequencer_view:
  188. layout.prop(st, "show_seconds")
  189. layout.prop(st, "show_frame_indicator")
  190. layout.prop(st, "show_strip_offset")
  191. layout.prop(st, "show_marker_lines")
  192. layout.separator()
  193. layout.menu("SEQUENCER_MT_view_cache")
  194. layout.prop_menu_enum(st, "waveform_display_type")
  195. if is_preview:
  196. if st.display_mode == 'IMAGE':
  197. layout.prop(st, "show_safe_areas")
  198. layout.prop(st, "show_metadata")
  199. elif st.display_mode == 'WAVEFORM':
  200. layout.prop(st, "show_separate_color")
  201. layout.separator()
  202. layout.operator("render.opengl", text="Sequence Render Image", icon='RENDER_STILL').sequencer = True
  203. props = layout.operator("render.opengl", text="Sequence Render Animation", icon='RENDER_ANIMATION')
  204. props.animation = True
  205. props.sequencer = True
  206. layout.separator()
  207. layout.menu("INFO_MT_area")
  208. class SEQUENCER_MT_select_handle(Menu):
  209. bl_label = "Select Handle"
  210. def draw(self, _context):
  211. layout = self.layout
  212. layout.operator("sequencer.select_handles", text="Both").side = 'BOTH'
  213. layout.operator("sequencer.select_handles", text="Left").side = 'LEFT'
  214. layout.operator("sequencer.select_handles", text="Right").side = 'RIGHT'
  215. class SEQUENCER_MT_select_channel(Menu):
  216. bl_label = "Select Channel"
  217. def draw(self, _context):
  218. layout = self.layout
  219. layout.operator("sequencer.select_active_side", text="Left").side = 'LEFT'
  220. layout.operator("sequencer.select_active_side", text="Right").side = 'RIGHT'
  221. class SEQUENCER_MT_select_linked(Menu):
  222. bl_label = "Select Linked"
  223. def draw(self, _context):
  224. layout = self.layout
  225. layout.operator("sequencer.select_linked", text="All")
  226. layout.operator("sequencer.select_less", text="Less")
  227. layout.operator("sequencer.select_more", text="More")
  228. class SEQUENCER_MT_select_playhead(Menu):
  229. bl_label = "Select Playhead"
  230. def draw(self, _context):
  231. layout = self.layout
  232. props = layout.operator("sequencer.select", text="Left")
  233. props.left_right = 'LEFT'
  234. props.linked_time = True
  235. props = layout.operator("sequencer.select", text="Right")
  236. props.left_right = 'RIGHT'
  237. props.linked_time = True
  238. class SEQUENCER_MT_select(Menu):
  239. bl_label = "Select"
  240. def draw(self, _context):
  241. layout = self.layout
  242. layout.operator("sequencer.select_all", text="All").action = 'SELECT'
  243. layout.operator("sequencer.select_all", text="None").action = 'DESELECT'
  244. layout.operator("sequencer.select_all", text="Invert").action = 'INVERT'
  245. layout.separator()
  246. layout.operator("sequencer.select_box", text="Box Select")
  247. layout.separator()
  248. layout.menu("SEQUENCER_MT_select_playhead", text="Playhead")
  249. layout.menu("SEQUENCER_MT_select_handle", text="Handle")
  250. layout.menu("SEQUENCER_MT_select_channel", text="Channel")
  251. layout.menu("SEQUENCER_MT_select_linked", text="Linked")
  252. layout.separator()
  253. layout.operator_menu_enum("sequencer.select_grouped", "type", text="Grouped")
  254. class SEQUENCER_MT_marker(Menu):
  255. bl_label = "Marker"
  256. def draw(self, context):
  257. layout = self.layout
  258. st = context.space_data
  259. is_sequencer_view = st.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'}
  260. from bl_ui.space_time import marker_menu_generic
  261. marker_menu_generic(layout, context)
  262. if is_sequencer_view:
  263. layout.prop(st, "use_marker_sync")
  264. class SEQUENCER_MT_change(Menu):
  265. bl_label = "Change"
  266. def draw(self, context):
  267. layout = self.layout
  268. strip = act_strip(context)
  269. layout.operator_context = 'INVOKE_REGION_WIN'
  270. layout.operator_menu_enum("sequencer.change_effect_input", "swap")
  271. layout.operator_menu_enum("sequencer.change_effect_type", "type")
  272. prop = layout.operator("sequencer.change_path", text="Path/Files")
  273. if strip:
  274. strip_type = strip.type
  275. if strip_type == 'IMAGE':
  276. prop.filter_image = True
  277. elif strip_type == 'MOVIE':
  278. prop.filter_movie = True
  279. elif strip_type == 'SOUND':
  280. prop.filter_sound = True
  281. class SEQUENCER_MT_navigation(Menu):
  282. bl_label = "Navigation"
  283. def draw(self, _context):
  284. layout = self.layout
  285. layout.operator("screen.animation_play")
  286. layout.separator()
  287. layout.operator("sequencer.view_frame", text="Go to Playhead")
  288. layout.separator()
  289. props = layout.operator("sequencer.strip_jump", text="Jump to Previous Strip")
  290. props.next = False
  291. props.center = False
  292. props = layout.operator("sequencer.strip_jump", text="Jump to Next Strip")
  293. props.next = True
  294. props.center = False
  295. layout.separator()
  296. props = layout.operator("sequencer.strip_jump", text="Jump to Previous Strip (Center)")
  297. props.next = False
  298. props.center = True
  299. props = layout.operator("sequencer.strip_jump", text="Jump to Next Strip (Center)")
  300. props.next = True
  301. props.center = True
  302. class SEQUENCER_MT_add(Menu):
  303. bl_label = "Add"
  304. bl_translation_context = i18n_contexts.operator_default
  305. def draw(self, context):
  306. layout = self.layout
  307. layout.operator_context = 'INVOKE_REGION_WIN'
  308. bpy_data_scenes_len = len(bpy.data.scenes)
  309. if bpy_data_scenes_len > 10:
  310. layout.operator_context = 'INVOKE_DEFAULT'
  311. layout.operator("sequencer.scene_strip_add", text="Scene...", icon='SCENE_DATA')
  312. elif bpy_data_scenes_len > 1:
  313. layout.operator_menu_enum("sequencer.scene_strip_add", "scene", text="Scene", icon='SCENE_DATA')
  314. else:
  315. layout.menu("SEQUENCER_MT_add_empty", text="Scene", icon='SCENE_DATA')
  316. del bpy_data_scenes_len
  317. bpy_data_movieclips_len = len(bpy.data.movieclips)
  318. if bpy_data_movieclips_len > 10:
  319. layout.operator_context = 'INVOKE_DEFAULT'
  320. layout.operator("sequencer.movieclip_strip_add", text="Clip...", icon='TRACKER')
  321. elif bpy_data_movieclips_len > 0:
  322. layout.operator_menu_enum("sequencer.movieclip_strip_add", "clip", text="Clip", icon='TRACKER')
  323. else:
  324. layout.menu("SEQUENCER_MT_add_empty", text="Clip", icon='TRACKER')
  325. del bpy_data_movieclips_len
  326. bpy_data_masks_len = len(bpy.data.masks)
  327. if bpy_data_masks_len > 10:
  328. layout.operator_context = 'INVOKE_DEFAULT'
  329. layout.operator("sequencer.mask_strip_add", text="Mask...", icon='MOD_MASK')
  330. elif bpy_data_masks_len > 0:
  331. layout.operator_menu_enum("sequencer.mask_strip_add", "mask", text="Mask", icon='MOD_MASK')
  332. else:
  333. layout.menu("SEQUENCER_MT_add_empty", text="Mask", icon='MOD_MASK')
  334. del bpy_data_masks_len
  335. layout.separator()
  336. layout.operator("sequencer.movie_strip_add", text="Movie", icon='FILE_MOVIE')
  337. layout.operator("sequencer.sound_strip_add", text="Sound", icon='FILE_SOUND')
  338. layout.operator("sequencer.image_strip_add", text="Image/Sequence", icon='FILE_IMAGE')
  339. layout.separator()
  340. layout.operator_context = 'INVOKE_REGION_WIN'
  341. layout.operator("sequencer.effect_strip_add", text="Color", icon='COLOR').type = 'COLOR'
  342. layout.operator("sequencer.effect_strip_add", text="Text", icon='FONT_DATA').type = 'TEXT'
  343. layout.separator()
  344. layout.operator("sequencer.effect_strip_add", text="Adjustment Layer", icon='COLOR').type = 'ADJUSTMENT'
  345. layout.operator_context = 'INVOKE_DEFAULT'
  346. layout.menu("SEQUENCER_MT_add_effect", icon='SHADERFX')
  347. col = layout.column()
  348. col.menu("SEQUENCER_MT_add_transitions", icon='ARROW_LEFTRIGHT')
  349. col.enabled = selected_sequences_len(context) >= 2
  350. class SEQUENCER_MT_add_empty(Menu):
  351. bl_label = "Empty"
  352. def draw(self, _context):
  353. layout = self.layout
  354. layout.label(text="No Items Available")
  355. class SEQUENCER_MT_add_transitions(Menu):
  356. bl_label = "Transitions"
  357. def draw(self, context):
  358. layout = self.layout
  359. col = layout.column()
  360. col.operator("sequencer.crossfade_sounds", text="Sound Crossfade")
  361. col.separator()
  362. col.operator("sequencer.effect_strip_add", text="Cross").type = 'CROSS'
  363. col.operator("sequencer.effect_strip_add", text="Gamma Cross").type = 'GAMMA_CROSS'
  364. col.separator()
  365. col.operator("sequencer.effect_strip_add", text="Wipe").type = 'WIPE'
  366. col.enabled = selected_sequences_len(context) >= 2
  367. class SEQUENCER_MT_add_effect(Menu):
  368. bl_label = "Effect Strip"
  369. def draw(self, context):
  370. layout = self.layout
  371. layout.operator_context = 'INVOKE_REGION_WIN'
  372. col = layout.column()
  373. col.operator("sequencer.effect_strip_add", text="Add").type = 'ADD'
  374. col.operator("sequencer.effect_strip_add", text="Subtract").type = 'SUBTRACT'
  375. col.operator("sequencer.effect_strip_add", text="Multiply").type = 'MULTIPLY'
  376. col.operator("sequencer.effect_strip_add", text="Over Drop").type = 'OVER_DROP'
  377. col.operator("sequencer.effect_strip_add", text="Alpha Over").type = 'ALPHA_OVER'
  378. col.operator("sequencer.effect_strip_add", text="Alpha Under").type = 'ALPHA_UNDER'
  379. col.operator("sequencer.effect_strip_add", text="Color Mix").type = 'COLORMIX'
  380. col.enabled = selected_sequences_len(context) >= 2
  381. layout.separator()
  382. layout.operator("sequencer.effect_strip_add", text="Multicam Selector").type = 'MULTICAM'
  383. layout.separator()
  384. col = layout.column()
  385. col.operator("sequencer.effect_strip_add", text="Transform").type = 'TRANSFORM'
  386. col.operator("sequencer.effect_strip_add", text="Speed Control").type = 'SPEED'
  387. col.separator()
  388. col.operator("sequencer.effect_strip_add", text="Glow").type = 'GLOW'
  389. col.operator("sequencer.effect_strip_add", text="Gaussian Blur").type = 'GAUSSIAN_BLUR'
  390. col.enabled = selected_sequences_len(context) != 0
  391. class SEQUENCER_MT_strip_transform(Menu):
  392. bl_label = "Transform"
  393. def draw(self, _context):
  394. layout = self.layout
  395. layout.operator("transform.seq_slide", text="Move")
  396. layout.operator("transform.transform", text="Move/Extend from Playhead").mode = 'TIME_EXTEND'
  397. layout.operator("sequencer.slip", text="Slip Strip Contents")
  398. layout.separator()
  399. layout.operator("sequencer.snap")
  400. layout.operator("sequencer.offset_clear")
  401. layout.separator()
  402. layout.operator_menu_enum("sequencer.swap", "side")
  403. layout.separator()
  404. layout.operator("sequencer.gap_remove").all = False
  405. layout.operator("sequencer.gap_insert")
  406. class SEQUENCER_MT_strip_input(Menu):
  407. bl_label = "Inputs"
  408. def draw(self, context):
  409. layout = self.layout
  410. strip = act_strip(context)
  411. layout.operator("sequencer.reload", text="Reload Strips")
  412. layout.operator("sequencer.reload", text="Reload Strips and Adjust Length").adjust_length = True
  413. prop = layout.operator("sequencer.change_path", text="Change Path/Files")
  414. layout.operator("sequencer.swap_data", text="Swap Data")
  415. if strip:
  416. strip_type = strip.type
  417. if strip_type == 'IMAGE':
  418. prop.filter_image = True
  419. elif strip_type == 'MOVIE':
  420. prop.filter_movie = True
  421. elif strip_type == 'SOUND':
  422. prop.filter_sound = True
  423. class SEQUENCER_MT_strip_lock_mute(Menu):
  424. bl_label = "Lock/Mute"
  425. def draw(self, _context):
  426. layout = self.layout
  427. layout.operator("sequencer.lock")
  428. layout.operator("sequencer.unlock")
  429. layout.separator()
  430. layout.operator("sequencer.mute").unselected = False
  431. layout.operator("sequencer.unmute").unselected = False
  432. layout.operator("sequencer.mute", text="Mute Unselected Strips").unselected = True
  433. layout.operator("sequencer.unmute", text="Unmute Deselected Strips").unselected = True
  434. class SEQUENCER_MT_strip_effect(Menu):
  435. bl_label = "Effect Strip"
  436. def draw(self, _context):
  437. layout = self.layout
  438. layout.operator_menu_enum("sequencer.change_effect_input", "swap")
  439. layout.operator_menu_enum("sequencer.change_effect_type", "type")
  440. layout.operator("sequencer.reassign_inputs")
  441. layout.operator("sequencer.swap_inputs")
  442. class SEQUENCER_MT_strip_movie(Menu):
  443. bl_label = "Movie Strip"
  444. def draw(self, _context):
  445. layout = self.layout
  446. layout.operator("sequencer.rendersize")
  447. layout.operator("sequencer.deinterlace_selected_movies")
  448. class SEQUENCER_MT_strip(Menu):
  449. bl_label = "Strip"
  450. def draw(self, context):
  451. layout = self.layout
  452. layout.operator_context = 'INVOKE_REGION_WIN'
  453. layout.separator()
  454. layout.menu("SEQUENCER_MT_strip_transform")
  455. layout.separator()
  456. layout.operator("sequencer.cut", text="Cut").type = 'SOFT'
  457. layout.operator("sequencer.cut", text="Hold Cut").type = 'HARD'
  458. layout.separator()
  459. layout.operator("sequencer.copy", text="Copy")
  460. layout.operator("sequencer.paste", text="Paste")
  461. layout.operator("sequencer.duplicate_move")
  462. layout.operator("sequencer.delete", text="Delete...")
  463. strip = act_strip(context)
  464. if strip:
  465. strip_type = strip.type
  466. if strip_type != 'SOUND':
  467. layout.separator()
  468. layout.operator_menu_enum("sequencer.strip_modifier_add", "type", text="Add Modifier")
  469. layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
  470. if strip_type in {
  471. 'CROSS', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
  472. 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP', 'WIPE', 'GLOW',
  473. 'TRANSFORM', 'COLOR', 'SPEED', 'MULTICAM', 'ADJUSTMENT',
  474. 'GAUSSIAN_BLUR', 'TEXT',
  475. }:
  476. layout.separator()
  477. layout.menu("SEQUENCER_MT_strip_effect")
  478. elif strip_type == 'MOVIE':
  479. layout.separator()
  480. layout.menu("SEQUENCER_MT_strip_movie")
  481. elif strip_type == 'IMAGE':
  482. layout.separator()
  483. layout.operator("sequencer.rendersize")
  484. layout.operator("sequencer.images_separate")
  485. elif strip_type == 'META':
  486. layout.separator()
  487. layout.operator("sequencer.meta_make")
  488. layout.operator("sequencer.meta_separate")
  489. layout.operator("sequencer.meta_toggle", text="Toggle Meta")
  490. if strip_type != 'META':
  491. layout.separator()
  492. layout.operator("sequencer.meta_make")
  493. layout.operator("sequencer.meta_toggle", text="Toggle Meta")
  494. layout.separator()
  495. layout.menu("SEQUENCER_MT_strip_lock_mute")
  496. layout.separator()
  497. layout.menu("SEQUENCER_MT_strip_input")
  498. layout.separator()
  499. layout.operator("sequencer.rebuild_proxy")
  500. class SEQUENCER_MT_context_menu(Menu):
  501. bl_label = "Sequencer Context Menu"
  502. def draw(self, context):
  503. layout = self.layout
  504. layout.operator_context = 'INVOKE_REGION_WIN'
  505. layout.operator("sequencer.cut", text="Cut").type = 'SOFT'
  506. layout.separator()
  507. layout.operator("sequencer.copy", text="Copy", icon='COPYDOWN')
  508. layout.operator("sequencer.paste", text="Paste", icon='PASTEDOWN')
  509. layout.operator("sequencer.duplicate_move")
  510. layout.operator("sequencer.delete", text="Delete...")
  511. layout.separator()
  512. layout.operator("sequencer.slip", text="Slip Strip Contents")
  513. layout.operator("sequencer.snap")
  514. layout.separator()
  515. layout.operator("sequencer.gap_remove").all = False
  516. layout.operator("sequencer.gap_insert")
  517. strip = act_strip(context)
  518. if strip:
  519. strip_type = strip.type
  520. if strip_type != 'SOUND':
  521. layout.separator()
  522. layout.operator_menu_enum("sequencer.strip_modifier_add", "type", text="Add Modifier")
  523. layout.operator("sequencer.strip_modifier_copy", text="Copy Modifiers to Selection")
  524. if selected_sequences_len(context) >= 2:
  525. layout.separator()
  526. col = layout.column()
  527. col.menu("SEQUENCER_MT_add_transitions", text="Add Transition")
  528. elif selected_sequences_len(context) >= 2:
  529. layout.separator()
  530. layout.operator("sequencer.crossfade_sounds", text="Crossfade Sounds")
  531. if strip_type in {
  532. 'CROSS', 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
  533. 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP', 'WIPE', 'GLOW',
  534. 'TRANSFORM', 'COLOR', 'SPEED', 'MULTICAM', 'ADJUSTMENT',
  535. 'GAUSSIAN_BLUR', 'TEXT',
  536. }:
  537. layout.separator()
  538. layout.menu("SEQUENCER_MT_strip_effect")
  539. elif strip_type in 'MOVIE':
  540. layout.separator()
  541. layout.menu("SEQUENCER_MT_strip_movie")
  542. elif strip_type == 'IMAGE':
  543. layout.separator()
  544. layout.operator("sequencer.rendersize")
  545. layout.operator("sequencer.images_separate")
  546. elif strip_type == 'META':
  547. layout.separator()
  548. layout.operator("sequencer.meta_make")
  549. layout.operator("sequencer.meta_separate")
  550. layout.operator("sequencer.meta_toggle", text="Toggle Meta")
  551. if strip_type != 'META':
  552. layout.separator()
  553. layout.operator("sequencer.meta_make")
  554. layout.operator("sequencer.meta_toggle", text="Toggle Meta")
  555. layout.separator()
  556. layout.menu("SEQUENCER_MT_strip_lock_mute")
  557. class SequencerButtonsPanel:
  558. bl_space_type = 'SEQUENCE_EDITOR'
  559. bl_region_type = 'UI'
  560. @staticmethod
  561. def has_sequencer(context):
  562. return (context.space_data.view_type in {'SEQUENCER', 'SEQUENCER_PREVIEW'})
  563. @classmethod
  564. def poll(cls, context):
  565. return cls.has_sequencer(context) and (act_strip(context) is not None)
  566. class SequencerButtonsPanel_Output:
  567. bl_space_type = 'SEQUENCE_EDITOR'
  568. bl_region_type = 'UI'
  569. @staticmethod
  570. def has_preview(context):
  571. st = context.space_data
  572. return (st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}) or st.show_backdrop
  573. @classmethod
  574. def poll(cls, context):
  575. return cls.has_preview(context)
  576. class SEQUENCER_PT_strip(SequencerButtonsPanel, Panel):
  577. bl_label = ""
  578. bl_options = {'HIDE_HEADER'}
  579. bl_category = "Strip"
  580. def draw(self, context):
  581. layout = self.layout
  582. strip = act_strip(context)
  583. strip_type = strip.type
  584. if strip_type in {
  585. 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER', 'MULTIPLY',
  586. 'OVER_DROP', 'GLOW', 'TRANSFORM', 'SPEED', 'MULTICAM',
  587. 'GAUSSIAN_BLUR', 'COLORMIX',
  588. }:
  589. icon_header = 'SHADERFX'
  590. elif strip_type in {
  591. 'CROSS', 'GAMMA_CROSS', 'WIPE',
  592. }:
  593. icon_header = 'ARROW_LEFTRIGHT'
  594. elif strip_type == 'SCENE':
  595. icon_header = 'SCENE_DATA'
  596. elif strip_type == 'MOVIECLIP':
  597. icon_header = 'TRACKER'
  598. elif strip_type == 'MASK':
  599. icon_header = 'MOD_MASK'
  600. elif strip_type == 'MOVIE':
  601. icon_header = 'FILE_MOVIE'
  602. elif strip_type == 'SOUND':
  603. icon_header = 'FILE_SOUND'
  604. elif strip_type == 'IMAGE':
  605. icon_header = 'FILE_IMAGE'
  606. elif strip_type == 'COLOR':
  607. icon_header = 'COLOR'
  608. elif strip_type == 'TEXT':
  609. icon_header = 'FONT_DATA'
  610. elif strip_type == 'ADJUSTMENT':
  611. icon_header = 'COLOR'
  612. else:
  613. icon_header = 'SEQ_SEQUENCER'
  614. row = layout.row()
  615. row.label(text="", icon=icon_header)
  616. row.prop(strip, "name", text="")
  617. row.prop(strip, "mute", toggle=True, icon_only=True, emboss=False)
  618. class SEQUENCER_PT_adjust_transform_offset(SequencerButtonsPanel, Panel):
  619. bl_label = "Offset"
  620. bl_parent_id = "SEQUENCER_PT_adjust_transform"
  621. bl_options = {'DEFAULT_CLOSED'}
  622. bl_category = "Strip"
  623. @classmethod
  624. def poll(cls, context):
  625. strip = act_strip(context)
  626. return strip.type != 'SOUND'
  627. def draw_header(self, context):
  628. strip = act_strip(context)
  629. self.layout.prop(strip, "use_translation", text="")
  630. def draw(self, context):
  631. strip = act_strip(context)
  632. layout = self.layout
  633. layout.use_property_split = True
  634. layout.active = strip.use_translation and (not strip.mute)
  635. col = layout.column(align=True)
  636. col.prop(strip.transform, "offset_x", text="Position X")
  637. col.prop(strip.transform, "offset_y", text="Y")
  638. class SEQUENCER_PT_adjust_transform_crop(SequencerButtonsPanel, Panel):
  639. bl_label = "Crop"
  640. bl_parent_id = "SEQUENCER_PT_adjust_transform"
  641. bl_options = {'DEFAULT_CLOSED'}
  642. bl_category = "Strip"
  643. @classmethod
  644. def poll(cls, context):
  645. strip = act_strip(context)
  646. return strip.type != 'SOUND'
  647. def draw_header(self, context):
  648. strip = act_strip(context)
  649. self.layout.prop(strip, "use_crop", text="")
  650. def draw(self, context):
  651. strip = act_strip(context)
  652. layout = self.layout
  653. layout.use_property_split = True
  654. layout.active = strip.use_crop and (not strip.mute)
  655. col = layout.column(align=True)
  656. col.prop(strip.crop, "min_x")
  657. col.prop(strip.crop, "max_x")
  658. col.prop(strip.crop, "max_y")
  659. col.prop(strip.crop, "min_y")
  660. class SEQUENCER_PT_effect(SequencerButtonsPanel, Panel):
  661. bl_label = "Effect Strip"
  662. bl_category = "Strip"
  663. @classmethod
  664. def poll(cls, context):
  665. if not cls.has_sequencer(context):
  666. return False
  667. strip = act_strip(context)
  668. if not strip:
  669. return False
  670. return strip.type in {
  671. 'ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
  672. 'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
  673. 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', 'SPEED',
  674. 'MULTICAM', 'GAUSSIAN_BLUR', 'TEXT', 'COLORMIX'
  675. }
  676. def draw(self, context):
  677. layout = self.layout
  678. layout.use_property_split = True
  679. strip = act_strip(context)
  680. layout.active = not strip.mute
  681. if strip.input_count > 0:
  682. col = layout.column()
  683. col.enabled = False
  684. col.prop(strip, "input_1")
  685. if strip.input_count > 1:
  686. col.prop(strip, "input_2")
  687. strip_type = strip.type
  688. if strip_type == 'COLOR':
  689. layout.prop(strip, "color")
  690. elif strip_type == 'WIPE':
  691. col = layout.column()
  692. col.prop(strip, "transition_type")
  693. col.alignment = 'RIGHT'
  694. col.row().prop(strip, "direction", expand=True)
  695. col = layout.column()
  696. col.prop(strip, "blur_width", slider=True)
  697. if strip.transition_type in {'SINGLE', 'DOUBLE'}:
  698. col.prop(strip, "angle")
  699. elif strip_type == 'GLOW':
  700. flow = layout.column_flow()
  701. flow.prop(strip, "threshold", slider=True)
  702. flow.prop(strip, "clamp", slider=True)
  703. flow.prop(strip, "boost_factor")
  704. flow.prop(strip, "blur_radius")
  705. row = layout.row()
  706. row.prop(strip, "quality", slider=True)
  707. row.prop(strip, "use_only_boost")
  708. elif strip_type == 'SPEED':
  709. layout.prop(strip, "use_default_fade", text="Stretch to input strip length")
  710. if not strip.use_default_fade:
  711. layout.prop(strip, "use_as_speed")
  712. if strip.use_as_speed:
  713. layout.prop(strip, "speed_factor")
  714. else:
  715. layout.prop(strip, "speed_factor", text="Frame Number")
  716. layout.prop(strip, "use_scale_to_length")
  717. elif strip_type == 'TRANSFORM':
  718. col = layout.column()
  719. col.prop(strip, "interpolation")
  720. col.prop(strip, "translation_unit")
  721. col = layout.column(align=True)
  722. col.prop(strip, "translate_start_x", text="Position X")
  723. col.prop(strip, "translate_start_y", text="Y")
  724. col.separator()
  725. colsub = col.column(align=True)
  726. colsub.prop(strip, "use_uniform_scale")
  727. if strip.use_uniform_scale:
  728. colsub = col.column(align=True)
  729. colsub.prop(strip, "scale_start_x", text="Scale")
  730. else:
  731. col.prop(strip, "scale_start_x", text="Scale X")
  732. col.prop(strip, "scale_start_y", text="Y")
  733. col.separator()
  734. col.prop(strip, "rotation_start", text="Rotation")
  735. elif strip_type == 'MULTICAM':
  736. col = layout.column(align=True)
  737. strip_channel = strip.channel
  738. col.prop(strip, "multicam_source", text="Source Channel")
  739. # The multicam strip needs at least 2 strips to be useful
  740. if strip_channel > 2:
  741. BT_ROW = 4
  742. col.label(text=" Cut to")
  743. row = col.row()
  744. for i in range(1, strip_channel):
  745. if (i % BT_ROW) == 1:
  746. row = col.row(align=True)
  747. # Workaround - .enabled has to have a separate UI block to work
  748. if i == strip.multicam_source:
  749. sub = row.row(align=True)
  750. sub.enabled = False
  751. sub.operator("sequencer.cut_multicam", text=f"{i:d}").camera = i
  752. else:
  753. sub_1 = row.row(align=True)
  754. sub_1.enabled = True
  755. sub_1.operator("sequencer.cut_multicam", text=f"{i:d}").camera = i
  756. if strip.channel > BT_ROW and (strip_channel - 1) % BT_ROW:
  757. for i in range(strip.channel, strip_channel + ((BT_ROW + 1 - strip_channel) % BT_ROW)):
  758. row.label(text="")
  759. else:
  760. col.separator()
  761. col.label(text="Two or more channels are needed below this strip", icon='INFO')
  762. elif strip_type == 'TEXT':
  763. col = layout.column()
  764. col.prop(strip, "text")
  765. col.template_ID(strip, "font", open="font.open", unlink="font.unlink")
  766. col.prop(strip, "font_size")
  767. row = col.row()
  768. row.prop(strip, "color")
  769. row = col.row()
  770. row.prop(strip, "use_shadow")
  771. rowsub = row.row()
  772. rowsub.active = strip.use_shadow
  773. rowsub.prop(strip, "shadow_color", text="")
  774. col.prop(strip, "align_x", text="Horizontal")
  775. col.prop(strip, "align_y", text="Vertical")
  776. row = col.row(align=True)
  777. row.prop(strip, "location", text="Location", slider=True)
  778. col.prop(strip, "wrap_width")
  779. layout.operator("sequencer.export_subtitles", text="Export Subtitles", icon='EXPORT')
  780. col = layout.column(align=True)
  781. if strip_type == 'SPEED':
  782. col.prop(strip, "multiply_speed")
  783. elif strip_type in {'CROSS', 'GAMMA_CROSS', 'WIPE', 'ALPHA_OVER', 'ALPHA_UNDER', 'OVER_DROP'}:
  784. col.prop(strip, "use_default_fade", text="Default fade")
  785. if not strip.use_default_fade:
  786. col.prop(strip, "effect_fader", text="Effect Fader")
  787. elif strip_type == 'GAUSSIAN_BLUR':
  788. col = layout.column(align=True)
  789. col.prop(strip, "size_x", text="Size X")
  790. col.prop(strip, "size_y", text="Y")
  791. elif strip_type == 'COLORMIX':
  792. layout.prop(strip, "blend_effect", text="Blend Mode")
  793. row = layout.row(align=True)
  794. row.prop(strip, "factor", slider=True)
  795. class SEQUENCER_PT_source(SequencerButtonsPanel, Panel):
  796. bl_label = "Source"
  797. bl_options = {'DEFAULT_CLOSED'}
  798. bl_category = "Strip"
  799. @classmethod
  800. def poll(cls, context):
  801. if not cls.has_sequencer(context):
  802. return False
  803. strip = act_strip(context)
  804. if not strip:
  805. return False
  806. return strip.type in {'MOVIE', 'IMAGE', 'SOUND'}
  807. def draw(self, context):
  808. layout = self.layout
  809. layout.use_property_split = True
  810. layout.use_property_decorate = False
  811. scene = context.scene
  812. strip = act_strip(context)
  813. strip_type = strip.type
  814. layout.active = not strip.mute
  815. # Draw a filename if we have one.
  816. if strip_type == 'SOUND':
  817. sound = strip.sound
  818. layout.template_ID(strip, "sound", open="sound.open")
  819. if sound is not None:
  820. col = layout.column()
  821. col.prop(sound, "filepath", text="")
  822. col.alignment = 'RIGHT'
  823. sub = col.column(align=True)
  824. split = sub.split(factor=0.5, align=True)
  825. split.alignment = 'RIGHT'
  826. if sound.packed_file:
  827. split.label(text="Unpack")
  828. split.operator("sound.unpack", icon='PACKAGE', text="")
  829. else:
  830. split.label(text="Pack")
  831. split.operator("sound.pack", icon='UGLYPACKAGE', text="")
  832. layout.prop(sound, "use_memory_cache")
  833. else:
  834. if strip_type == 'IMAGE':
  835. col = layout.column()
  836. col.prop(strip, "directory", text="")
  837. # Current element for the filename.
  838. elem = strip.strip_elem_from_frame(scene.frame_current)
  839. if elem:
  840. col.prop(elem, "filename", text="") # strip.elements[0] could be a fallback
  841. col.prop(strip.colorspace_settings, "name", text="Color Space")
  842. col.prop(strip, "alpha_mode", text="Alpha")
  843. sub = col.column(align=True)
  844. sub.operator("sequencer.change_path", text="Change Data/Files", icon='FILEBROWSER').filter_image = True
  845. else: # elif strip_type == 'MOVIE':
  846. elem = strip.elements[0]
  847. col = layout.column()
  848. col.prop(strip, "filepath", text="")
  849. col.prop(strip.colorspace_settings, "name", text="Color Space")
  850. col.prop(strip, "mpeg_preseek")
  851. col.prop(strip, "stream_index")
  852. col.prop(strip, "use_deinterlace")
  853. if scene.render.use_multiview:
  854. layout.prop(strip, "use_multiview")
  855. col = layout.column()
  856. col.active = strip.use_multiview
  857. col.row().prop(strip, "views_format", expand=True)
  858. box = col.box()
  859. box.active = strip.views_format == 'STEREO_3D'
  860. box.template_image_stereo_3d(strip.stereo_3d_format)
  861. # Resolution.
  862. col = layout.column(align=True)
  863. col = col.box()
  864. split = col.split(factor=0.5, align=False)
  865. split.alignment = 'RIGHT'
  866. split.label(text="Resolution")
  867. size = (elem.orig_width, elem.orig_height) if elem else (0, 0)
  868. if size[0] and size[1]:
  869. split.alignment = 'LEFT'
  870. split.label(text="%dx%d" % size, translate=False)
  871. else:
  872. split.label(text="None")
  873. class SEQUENCER_PT_sound(SequencerButtonsPanel, Panel):
  874. bl_label = "Sound"
  875. bl_parent_id = ""
  876. bl_category = "Strip"
  877. @classmethod
  878. def poll(cls, context):
  879. if not cls.has_sequencer(context):
  880. return False
  881. strip = act_strip(context)
  882. if not strip:
  883. return False
  884. return (strip.type == 'SOUND')
  885. def draw(self, context):
  886. layout = self.layout
  887. layout.use_property_split = True
  888. strip = act_strip(context)
  889. sound = strip.sound
  890. layout.active = not strip.mute
  891. layout.template_ID(strip, "sound", open="sound.open")
  892. if sound is not None:
  893. layout.prop(sound, "filepath", text="")
  894. layout.use_property_split = True
  895. layout.use_property_decorate = False
  896. layout.alignment = 'RIGHT'
  897. sub = layout.column(align=True)
  898. split = sub.split(factor=0.5, align=True)
  899. split.alignment = 'RIGHT'
  900. if sound.packed_file:
  901. split.label(text="Unpack")
  902. split.operator("sound.unpack", icon='PACKAGE', text="")
  903. else:
  904. split.label(text="Pack")
  905. split.operator("sound.pack", icon='UGLYPACKAGE', text="")
  906. layout.prop(sound, "use_memory_cache")
  907. class SEQUENCER_PT_scene(SequencerButtonsPanel, Panel):
  908. bl_label = "Scene"
  909. bl_category = "Strip"
  910. @classmethod
  911. def poll(cls, context):
  912. if not cls.has_sequencer(context):
  913. return False
  914. strip = act_strip(context)
  915. if not strip:
  916. return False
  917. return (strip.type == 'SCENE')
  918. def draw(self, context):
  919. layout = self.layout
  920. layout.use_property_split = True
  921. layout.use_property_decorate = False
  922. strip = act_strip(context)
  923. layout.active = not strip.mute
  924. layout.template_ID(strip, "scene")
  925. scene = strip.scene
  926. layout.prop(strip, "scene_input")
  927. if scene:
  928. layout.prop(scene, "audio_volume", text="Volume")
  929. if strip.scene_input == 'CAMERA':
  930. layout.alignment = 'RIGHT'
  931. sub = layout.column(align=True)
  932. split = sub.split(factor=0.5, align=True)
  933. split.alignment = 'RIGHT'
  934. split.label(text="Camera")
  935. split.template_ID(strip, "scene_camera")
  936. layout.prop(strip, "use_grease_pencil", text="Show Grease Pencil")
  937. if scene:
  938. # Warning, this is not a good convention to follow.
  939. # Expose here because setting the alpha from the 'Render' menu is very inconvenient.
  940. # layout.label(text="Preview")
  941. layout.prop(scene.render, "film_transparent")
  942. class SEQUENCER_PT_mask(SequencerButtonsPanel, Panel):
  943. bl_label = "Mask"
  944. bl_category = "Strip"
  945. @classmethod
  946. def poll(cls, context):
  947. if not cls.has_sequencer(context):
  948. return False
  949. strip = act_strip(context)
  950. if not strip:
  951. return False
  952. return (strip.type == 'MASK')
  953. def draw(self, context):
  954. layout = self.layout
  955. layout.use_property_split = True
  956. strip = act_strip(context)
  957. layout.active = not strip.mute
  958. layout.template_ID(strip, "mask")
  959. mask = strip.mask
  960. if mask:
  961. sta = mask.frame_start
  962. end = mask.frame_end
  963. layout.label(text=iface_("Original frame range: %d-%d (%d)") % (sta, end, end - sta + 1), translate=False)
  964. class SEQUENCER_PT_time(SequencerButtonsPanel, Panel):
  965. bl_label = "Time"
  966. bl_options = {'DEFAULT_CLOSED'}
  967. bl_category = "Strip"
  968. @classmethod
  969. def poll(cls, context):
  970. if not cls.has_sequencer(context):
  971. return False
  972. strip = act_strip(context)
  973. if not strip:
  974. return False
  975. return strip.type
  976. def draw_header_preset(self, context):
  977. layout = self.layout
  978. layout.alignment = 'RIGHT'
  979. strip = act_strip(context)
  980. layout.prop(strip, "lock", text="", icon_only=True, emboss=False)
  981. def draw(self, context):
  982. from bpy.utils import smpte_from_frame
  983. layout = self.layout
  984. layout.use_property_split = False
  985. layout.use_property_decorate = False
  986. scene = context.scene
  987. frame_current = scene.frame_current
  988. strip = act_strip(context)
  989. is_effect = isinstance(strip, bpy.types.EffectSequence)
  990. # Get once.
  991. frame_start = strip.frame_start
  992. frame_final_start = strip.frame_final_start
  993. frame_final_end = strip.frame_final_end
  994. frame_final_duration = strip.frame_final_duration
  995. frame_offset_start = strip.frame_offset_start
  996. frame_offset_end = strip.frame_offset_end
  997. length_list = (
  998. str(frame_start),
  999. str(frame_final_end),
  1000. str(frame_final_duration),
  1001. str(frame_offset_start),
  1002. str(frame_offset_end),
  1003. )
  1004. if not is_effect:
  1005. length_list = length_list + (
  1006. str(strip.animation_offset_start),
  1007. str(strip.animation_offset_end),
  1008. )
  1009. max_length = max(len(x) for x in length_list)
  1010. max_factor = (1.9 - max_length) / 30
  1011. layout.enabled = not strip.lock
  1012. layout.active = not strip.mute
  1013. sub = layout.row(align=True)
  1014. split = sub.split(factor=0.5 + max_factor)
  1015. split.alignment = 'RIGHT'
  1016. split.label(text="Channel")
  1017. split.prop(strip, "channel", text="")
  1018. sub = layout.column(align=True)
  1019. split = sub.split(factor=0.5 + max_factor, align=True)
  1020. split.alignment = 'RIGHT'
  1021. split.label(text="Start")
  1022. split.prop(strip, "frame_start", text=smpte_from_frame(frame_start))
  1023. split = sub.split(factor=0.5 + max_factor, align=True)
  1024. split.alignment = 'RIGHT'
  1025. split.label(text="Duration")
  1026. split.prop(strip, "frame_final_duration", text=smpte_from_frame(frame_final_duration))
  1027. # Use label, editing this value from the UI allows negative values,
  1028. # users can adjust duration.
  1029. split = sub.split(factor=0.5 + max_factor, align=True)
  1030. split.alignment = 'RIGHT'
  1031. split.label(text="End")
  1032. split = split.split(factor=0.8 + max_factor, align=True)
  1033. split.label(text="{:>14}".format(smpte_from_frame(frame_final_end) + ":"))
  1034. split.alignment = 'RIGHT'
  1035. split.label(text=str(frame_final_end) + " ")
  1036. if not is_effect:
  1037. layout.alignment = 'RIGHT'
  1038. sub = layout.column(align=True)
  1039. split = sub.split(factor=0.5 + max_factor, align=True)
  1040. split.alignment = 'RIGHT'
  1041. split.label(text="Strip Offset Start")
  1042. split.prop(strip, "frame_offset_start", text=smpte_from_frame(frame_offset_start))
  1043. split = sub.split(factor=0.5 + max_factor, align=True)
  1044. split.alignment = 'RIGHT'
  1045. split.label(text="End")
  1046. split.prop(strip, "frame_offset_end", text=smpte_from_frame(frame_offset_end))
  1047. layout.alignment = 'RIGHT'
  1048. sub = layout.column(align=True)
  1049. split = sub.split(factor=0.5 + max_factor, align=True)
  1050. split.alignment = 'RIGHT'
  1051. split.label(text="Hold Offset Start")
  1052. split.prop(strip, "animation_offset_start", text=smpte_from_frame(strip.animation_offset_start))
  1053. split = sub.split(factor=0.5 + max_factor, align=True)
  1054. split.alignment = 'RIGHT'
  1055. split.label(text="End")
  1056. split.prop(strip, "animation_offset_end", text=smpte_from_frame(strip.animation_offset_end))
  1057. col = layout.column(align=True)
  1058. col = col.box()
  1059. col.active = (
  1060. (frame_current >= frame_final_start) and
  1061. (frame_current <= frame_final_start + frame_final_duration)
  1062. )
  1063. split = col.split(factor=0.5 + max_factor, align=True)
  1064. split.alignment = 'RIGHT'
  1065. split.label(text="Playhead")
  1066. split = split.split(factor=0.8 + max_factor, align=True)
  1067. playhead = frame_current - frame_final_start
  1068. split.label(text="{:>14}".format(smpte_from_frame(playhead) + ":"))
  1069. split.alignment = 'RIGHT'
  1070. split.label(text=str(playhead) + " ")
  1071. if strip.type == 'SCENE':
  1072. scene = strip.scene
  1073. if scene:
  1074. sta = scene.frame_start
  1075. end = scene.frame_end
  1076. split = col.split(factor=0.5 + max_factor)
  1077. split.alignment = 'RIGHT'
  1078. split.label(text="Original Frame Range")
  1079. split.alignment = 'LEFT'
  1080. split.label(text="%d-%d (%d)" % (sta, end, end - sta + 1), translate=False)
  1081. class SEQUENCER_PT_adjust(SequencerButtonsPanel, Panel):
  1082. bl_label = "Adjust"
  1083. bl_category = "Strip"
  1084. def draw(self, context):
  1085. pass
  1086. class SEQUENCER_PT_adjust_sound(SequencerButtonsPanel, Panel):
  1087. bl_label = "Sound"
  1088. bl_parent_id = "SEQUENCER_PT_adjust"
  1089. bl_category = "Strip"
  1090. @classmethod
  1091. def poll(cls, context):
  1092. strip = act_strip(context)
  1093. return strip.type == 'SOUND'
  1094. def draw(self, context):
  1095. layout = self.layout
  1096. layout.use_property_split = True
  1097. st = context.space_data
  1098. strip = act_strip(context)
  1099. sound = strip.sound
  1100. layout.active = not strip.mute
  1101. col = layout.column()
  1102. col.prop(strip, "volume", text="Volume")
  1103. col.prop(strip, "pitch")
  1104. col.prop(strip, "pan")
  1105. if sound is not None:
  1106. if st.waveform_display_type == 'DEFAULT_WAVEFORMS':
  1107. col.prop(strip, "show_waveform")
  1108. col.prop(sound, "use_mono")
  1109. class SEQUENCER_PT_adjust_comp(SequencerButtonsPanel, Panel):
  1110. bl_label = "Compositing"
  1111. bl_parent_id = "SEQUENCER_PT_adjust"
  1112. bl_category = "Strip"
  1113. @classmethod
  1114. def poll(cls, context):
  1115. strip = act_strip(context)
  1116. return strip.type != 'SOUND'
  1117. def draw(self, context):
  1118. layout = self.layout
  1119. layout.use_property_split = True
  1120. strip = act_strip(context)
  1121. layout.active = not strip.mute
  1122. col = layout.column()
  1123. col.prop(strip, "blend_type", text="Blend")
  1124. col.prop(strip, "blend_alpha", text="Opacity", slider=True)
  1125. class SEQUENCER_PT_adjust_transform(SequencerButtonsPanel, Panel):
  1126. bl_label = "Transform"
  1127. bl_parent_id = "SEQUENCER_PT_adjust"
  1128. bl_category = "Strip"
  1129. @classmethod
  1130. def poll(cls, context):
  1131. if not cls.has_sequencer(context):
  1132. return False
  1133. strip = act_strip(context)
  1134. if not strip:
  1135. return False
  1136. return strip.type in {
  1137. 'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'MASK',
  1138. 'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER',
  1139. 'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY',
  1140. 'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
  1141. 'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX'
  1142. }
  1143. def draw(self, context):
  1144. layout = self.layout
  1145. strip = act_strip(context)
  1146. layout.active = not strip.mute
  1147. split = layout.split()
  1148. col = split.column()
  1149. col.alignment = 'RIGHT'
  1150. col.label(text="Mirror")
  1151. col = split.column()
  1152. row = col.row(align=True)
  1153. row.prop(strip, "use_flip_x", text="X", toggle=True)
  1154. row.prop(strip, "use_flip_y", text="Y", toggle=True)
  1155. class SEQUENCER_PT_adjust_video(SequencerButtonsPanel, Panel):
  1156. bl_label = "Video"
  1157. bl_parent_id = "SEQUENCER_PT_adjust"
  1158. bl_options = {'DEFAULT_CLOSED'}
  1159. bl_category = "Strip"
  1160. @classmethod
  1161. def poll(cls, context):
  1162. if not cls.has_sequencer(context):
  1163. return False
  1164. strip = act_strip(context)
  1165. if not strip:
  1166. return False
  1167. return strip.type in {
  1168. 'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'MASK',
  1169. 'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER',
  1170. 'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY',
  1171. 'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
  1172. 'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX'
  1173. }
  1174. def draw(self, context):
  1175. layout = self.layout
  1176. layout.use_property_split = True
  1177. col = layout.column()
  1178. strip = act_strip(context)
  1179. layout.active = not strip.mute
  1180. col.prop(strip, "strobe")
  1181. if strip.type == 'MOVIECLIP':
  1182. col = layout.column()
  1183. col.label(text="Tracker")
  1184. col.prop(strip, "stabilize2d")
  1185. col = layout.column()
  1186. col.label(text="Distortion")
  1187. col.prop(strip, "undistort")
  1188. col.separator()
  1189. col.prop(strip, "playback_direction")
  1190. class SEQUENCER_PT_adjust_color(SequencerButtonsPanel, Panel):
  1191. bl_label = "Color"
  1192. bl_parent_id = "SEQUENCER_PT_adjust"
  1193. bl_options = {'DEFAULT_CLOSED'}
  1194. bl_category = "Strip"
  1195. @classmethod
  1196. def poll(cls, context):
  1197. if not cls.has_sequencer(context):
  1198. return False
  1199. strip = act_strip(context)
  1200. if not strip:
  1201. return False
  1202. return strip.type in {
  1203. 'MOVIE', 'IMAGE', 'SCENE', 'MOVIECLIP', 'MASK',
  1204. 'META', 'ADD', 'SUBTRACT', 'ALPHA_OVER',
  1205. 'ALPHA_UNDER', 'CROSS', 'GAMMA_CROSS', 'MULTIPLY',
  1206. 'OVER_DROP', 'WIPE', 'GLOW', 'TRANSFORM', 'COLOR',
  1207. 'MULTICAM', 'SPEED', 'ADJUSTMENT', 'COLORMIX'
  1208. }
  1209. def draw(self, context):
  1210. layout = self.layout
  1211. layout.use_property_split = True
  1212. strip = act_strip(context)
  1213. layout.active = not strip.mute
  1214. col = layout.column()
  1215. col.prop(strip, "color_saturation", text="Saturation")
  1216. col.prop(strip, "color_multiply", text="Multiply")
  1217. col.prop(strip, "use_float", text="Convert to Float")
  1218. class SEQUENCER_PT_cache_settings(SequencerButtonsPanel, Panel):
  1219. bl_label = "Cache Settings"
  1220. bl_category = "Proxy & Cache"
  1221. @classmethod
  1222. def poll(cls, context):
  1223. return cls.has_sequencer(context) and context.scene.sequence_editor
  1224. def draw(self, context):
  1225. layout = self.layout
  1226. layout.use_property_split = True
  1227. layout.use_property_decorate = False
  1228. ed = context.scene.sequence_editor
  1229. col = layout.column()
  1230. col.prop(ed, "use_cache_raw")
  1231. col.prop(ed, "use_cache_preprocessed")
  1232. col.prop(ed, "use_cache_composite")
  1233. col.prop(ed, "use_cache_final")
  1234. col.separator()
  1235. col.prop(ed, "recycle_max_cost")
  1236. class SEQUENCER_PT_proxy_settings(SequencerButtonsPanel, Panel):
  1237. bl_label = "Proxy Settings"
  1238. bl_category = "Proxy & Cache"
  1239. @classmethod
  1240. def poll(cls, context):
  1241. return cls.has_sequencer(context) and context.scene.sequence_editor
  1242. def draw(self, context):
  1243. layout = self.layout
  1244. layout.use_property_split = True
  1245. layout.use_property_decorate = False
  1246. ed = context.scene.sequence_editor
  1247. flow = layout.column_flow()
  1248. flow.prop(ed, "proxy_storage", text="Storage")
  1249. if ed.proxy_storage == 'PROJECT':
  1250. flow.prop(ed, "proxy_dir", text="Directory")
  1251. col = layout.column()
  1252. col.operator("sequencer.enable_proxies")
  1253. col.operator("sequencer.rebuild_proxy")
  1254. class SEQUENCER_PT_strip_proxy(SequencerButtonsPanel, Panel):
  1255. bl_label = "Strip Proxy & Timecode"
  1256. bl_category = "Proxy & Cache"
  1257. @classmethod
  1258. def poll(cls, context):
  1259. if not cls.has_sequencer(context) and context.scene.sequence_editor:
  1260. return False
  1261. strip = act_strip(context)
  1262. if not strip:
  1263. return False
  1264. return strip.type in {'MOVIE', 'IMAGE', 'SCENE', 'META', 'MULTICAM'}
  1265. def draw_header(self, context):
  1266. strip = act_strip(context)
  1267. self.layout.prop(strip, "use_proxy", text="")
  1268. def draw(self, context):
  1269. layout = self.layout
  1270. layout.use_property_split = True
  1271. layout.use_property_decorate = False
  1272. ed = context.scene.sequence_editor
  1273. strip = act_strip(context)
  1274. if strip.proxy:
  1275. proxy = strip.proxy
  1276. flow = layout.column_flow()
  1277. if ed.proxy_storage == 'PER_STRIP':
  1278. flow.prop(proxy, "use_proxy_custom_directory")
  1279. flow.prop(proxy, "use_proxy_custom_file")
  1280. if proxy.use_proxy_custom_directory and not proxy.use_proxy_custom_file:
  1281. flow.prop(proxy, "directory")
  1282. if proxy.use_proxy_custom_file:
  1283. flow.prop(proxy, "filepath")
  1284. box = layout.box()
  1285. row = box.row(align=True)
  1286. row.prop(strip.proxy, "build_25")
  1287. row.prop(strip.proxy, "build_75")
  1288. row = box.row(align=True)
  1289. row.prop(strip.proxy, "build_50")
  1290. row.prop(strip.proxy, "build_100")
  1291. layout.use_property_split = True
  1292. layout.use_property_decorate = False
  1293. layout.prop(proxy, "use_overwrite")
  1294. col = layout.column()
  1295. col.prop(proxy, "quality", text="Build JPEG Quality")
  1296. if strip.type == 'MOVIE':
  1297. col = layout.column()
  1298. col.prop(proxy, "timecode", text="Timecode Index")
  1299. class SEQUENCER_PT_strip_cache(SequencerButtonsPanel, Panel):
  1300. bl_label = "Strip Cache"
  1301. bl_category = "Proxy & Cache"
  1302. bl_options = {'DEFAULT_CLOSED'}
  1303. @classmethod
  1304. def poll(cls, context):
  1305. if not cls.has_sequencer(context):
  1306. return False
  1307. if act_strip(context) is not None:
  1308. return True
  1309. return False
  1310. def draw_header(self, context):
  1311. strip = act_strip(context)
  1312. self.layout.prop(strip, "override_cache_settings", text="")
  1313. def draw(self, context):
  1314. layout = self.layout
  1315. layout.use_property_split = True
  1316. layout.use_property_decorate = False
  1317. strip = act_strip(context)
  1318. layout.active = strip.override_cache_settings
  1319. col = layout.column()
  1320. col.prop(strip, "use_cache_raw")
  1321. col.prop(strip, "use_cache_preprocessed")
  1322. col.prop(strip, "use_cache_composite")
  1323. class SEQUENCER_PT_preview(SequencerButtonsPanel_Output, Panel):
  1324. bl_label = "Scene Preview/Render"
  1325. bl_space_type = 'SEQUENCE_EDITOR'
  1326. bl_region_type = 'UI'
  1327. bl_options = {'DEFAULT_CLOSED'}
  1328. bl_category = "View"
  1329. def draw(self, context):
  1330. layout = self.layout
  1331. layout.use_property_split = True
  1332. layout.use_property_decorate = False
  1333. render = context.scene.render
  1334. col = layout.column()
  1335. col.prop(render, "sequencer_gl_preview", text="Preview Shading")
  1336. if render.sequencer_gl_preview in ['SOLID', 'WIREFRAME']:
  1337. col.prop(render, "use_sequencer_override_scene_strip")
  1338. class SEQUENCER_PT_view(SequencerButtonsPanel_Output, Panel):
  1339. bl_label = "View Settings"
  1340. bl_category = "View"
  1341. def draw(self, context):
  1342. layout = self.layout
  1343. layout.use_property_split = True
  1344. layout.use_property_decorate = False
  1345. st = context.space_data
  1346. col = layout.column()
  1347. col.prop(st, "display_channel", text="Channel")
  1348. if st.display_mode == 'IMAGE':
  1349. col.prop(st, "show_overexposed")
  1350. elif st.display_mode == 'WAVEFORM':
  1351. col.prop(st, "show_separate_color")
  1352. col.prop(st, "proxy_render_size")
  1353. class SEQUENCER_PT_frame_overlay(SequencerButtonsPanel_Output, Panel):
  1354. bl_label = "Frame Overlay"
  1355. bl_category = "View"
  1356. bl_options = {'DEFAULT_CLOSED'}
  1357. def draw_header(self, context):
  1358. scene = context.scene
  1359. ed = scene.sequence_editor
  1360. self.layout.prop(ed, "show_overlay", text="")
  1361. def draw(self, context):
  1362. layout = self.layout
  1363. layout.use_property_split = True
  1364. layout.use_property_decorate = False
  1365. st = context.space_data
  1366. scene = context.scene
  1367. ed = scene.sequence_editor
  1368. layout.active = ed.show_overlay
  1369. col = layout.column()
  1370. col.prop(ed, "overlay_frame", text="Frame Offset")
  1371. col.prop(st, "overlay_type")
  1372. col.prop(ed, "use_overlay_lock")
  1373. class SEQUENCER_PT_view_safe_areas(SequencerButtonsPanel_Output, Panel):
  1374. bl_label = "Safe Areas"
  1375. bl_options = {'DEFAULT_CLOSED'}
  1376. bl_category = "View"
  1377. @classmethod
  1378. def poll(cls, context):
  1379. st = context.space_data
  1380. is_preview = st.view_type in {'PREVIEW', 'SEQUENCER_PREVIEW'}
  1381. return is_preview and (st.display_mode == 'IMAGE')
  1382. def draw_header(self, context):
  1383. st = context.space_data
  1384. self.layout.prop(st, "show_safe_areas", text="")
  1385. def draw(self, context):
  1386. layout = self.layout
  1387. layout.use_property_split = True
  1388. st = context.space_data
  1389. safe_data = context.scene.safe_areas
  1390. layout.active = st.show_safe_areas
  1391. col = layout.column()
  1392. sub = col.column()
  1393. sub.prop(safe_data, "title", slider=True)
  1394. sub.prop(safe_data, "action", slider=True)
  1395. class SEQUENCER_PT_view_safe_areas_center_cut(SequencerButtonsPanel_Output, Panel):
  1396. bl_label = "Center-Cut Safe Areas"
  1397. bl_parent_id = "SEQUENCER_PT_view_safe_areas"
  1398. bl_options = {'DEFAULT_CLOSED'}
  1399. bl_category = "View"
  1400. def draw_header(self, context):
  1401. st = context.space_data
  1402. layout = self.layout
  1403. layout.active = st.show_safe_areas
  1404. layout.prop(st, "show_safe_center", text="")
  1405. def draw(self, context):
  1406. layout = self.layout
  1407. layout.use_property_split = True
  1408. safe_data = context.scene.safe_areas
  1409. st = context.space_data
  1410. layout.active = st.show_safe_areas and st.show_safe_center
  1411. col = layout.column()
  1412. col.prop(safe_data, "title_center", slider=True)
  1413. class SEQUENCER_PT_modifiers(SequencerButtonsPanel, Panel):
  1414. bl_label = "Modifiers"
  1415. bl_category = "Modifiers"
  1416. def draw(self, context):
  1417. layout = self.layout
  1418. layout.use_property_split = True
  1419. strip = act_strip(context)
  1420. ed = context.scene.sequence_editor
  1421. layout.prop(strip, "use_linear_modifiers")
  1422. layout.operator_menu_enum("sequencer.strip_modifier_add", "type")
  1423. layout.operator("sequencer.strip_modifier_copy")
  1424. for mod in strip.modifiers:
  1425. box = layout.box()
  1426. row = box.row()
  1427. row.prop(mod, "show_expanded", text="", emboss=False)
  1428. row.prop(mod, "name", text="")
  1429. row.prop(mod, "mute", text="")
  1430. sub = row.row(align=True)
  1431. props = sub.operator("sequencer.strip_modifier_move", text="", icon='TRIA_UP')
  1432. props.name = mod.name
  1433. props.direction = 'UP'
  1434. props = sub.operator("sequencer.strip_modifier_move", text="", icon='TRIA_DOWN')
  1435. props.name = mod.name
  1436. props.direction = 'DOWN'
  1437. row.operator("sequencer.strip_modifier_remove", text="", icon='X', emboss=False).name = mod.name
  1438. if mod.show_expanded:
  1439. row = box.row()
  1440. row.prop(mod, "input_mask_type", expand=True)
  1441. if mod.input_mask_type == 'STRIP':
  1442. sequences_object = ed
  1443. if ed.meta_stack:
  1444. sequences_object = ed.meta_stack[-1]
  1445. box.prop_search(mod, "input_mask_strip", sequences_object, "sequences", text="Mask")
  1446. else:
  1447. box.prop(mod, "input_mask_id")
  1448. row = box.row()
  1449. row.prop(mod, "mask_time", expand=True)
  1450. if mod.type == 'COLOR_BALANCE':
  1451. box.prop(mod, "color_multiply")
  1452. draw_color_balance(box, mod.color_balance)
  1453. elif mod.type == 'CURVES':
  1454. box.template_curve_mapping(mod, "curve_mapping", type='COLOR', show_tone=True)
  1455. elif mod.type == 'HUE_CORRECT':
  1456. box.template_curve_mapping(mod, "curve_mapping", type='HUE')
  1457. elif mod.type == 'BRIGHT_CONTRAST':
  1458. col = box.column()
  1459. col.prop(mod, "bright")
  1460. col.prop(mod, "contrast")
  1461. elif mod.type == 'WHITE_BALANCE':
  1462. col = box.column()
  1463. col.prop(mod, "white_value")
  1464. elif mod.type == 'TONEMAP':
  1465. col = box.column()
  1466. col.prop(mod, "tonemap_type")
  1467. if mod.tonemap_type == 'RD_PHOTORECEPTOR':
  1468. col.prop(mod, "intensity")
  1469. col.prop(mod, "contrast")
  1470. col.prop(mod, "adaptation")
  1471. col.prop(mod, "correction")
  1472. elif mod.tonemap_type == 'RH_SIMPLE':
  1473. col.prop(mod, "key")
  1474. col.prop(mod, "offset")
  1475. col.prop(mod, "gamma")
  1476. class SEQUENCER_PT_grease_pencil(AnnotationDataPanel, SequencerButtonsPanel_Output, Panel):
  1477. bl_space_type = 'SEQUENCE_EDITOR'
  1478. bl_region_type = 'UI'
  1479. bl_category = "View"
  1480. # NOTE: this is just a wrapper around the generic GP Panel
  1481. # But, it should only show up when there are images in the preview region
  1482. class SEQUENCER_PT_grease_pencil_tools(GreasePencilToolsPanel, SequencerButtonsPanel_Output, Panel):
  1483. bl_space_type = 'SEQUENCE_EDITOR'
  1484. bl_region_type = 'UI'
  1485. bl_category = "View"
  1486. # NOTE: this is just a wrapper around the generic GP tools panel
  1487. # It contains access to some essential tools usually found only in
  1488. # toolbar, which doesn't exist here...
  1489. class SEQUENCER_PT_custom_props(SequencerButtonsPanel, PropertyPanel, Panel):
  1490. COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_EEVEE', 'BLENDER_WORKBENCH'}
  1491. _context_path = "scene.sequence_editor.active_strip"
  1492. _property_type = (bpy.types.Sequence,)
  1493. bl_category = "Strip"
  1494. classes = (
  1495. SEQUENCER_MT_change,
  1496. SEQUENCER_HT_header,
  1497. SEQUENCER_MT_editor_menus,
  1498. SEQUENCER_MT_range,
  1499. SEQUENCER_MT_view,
  1500. SEQUENCER_MT_view_cache,
  1501. SEQUENCER_MT_view_toggle,
  1502. SEQUENCER_MT_select_playhead,
  1503. SEQUENCER_MT_select_handle,
  1504. SEQUENCER_MT_select_channel,
  1505. SEQUENCER_MT_select_linked,
  1506. SEQUENCER_MT_select,
  1507. SEQUENCER_MT_marker,
  1508. SEQUENCER_MT_navigation,
  1509. SEQUENCER_MT_add,
  1510. SEQUENCER_MT_add_effect,
  1511. SEQUENCER_MT_add_transitions,
  1512. SEQUENCER_MT_add_empty,
  1513. SEQUENCER_MT_strip_effect,
  1514. SEQUENCER_MT_strip_movie,
  1515. SEQUENCER_MT_strip,
  1516. SEQUENCER_MT_strip_transform,
  1517. SEQUENCER_MT_strip_input,
  1518. SEQUENCER_MT_strip_lock_mute,
  1519. SEQUENCER_MT_context_menu,
  1520. SEQUENCER_PT_strip,
  1521. SEQUENCER_PT_adjust,
  1522. SEQUENCER_PT_adjust_comp,
  1523. SEQUENCER_PT_adjust_transform,
  1524. SEQUENCER_PT_adjust_transform_offset,
  1525. SEQUENCER_PT_adjust_transform_crop,
  1526. SEQUENCER_PT_adjust_video,
  1527. SEQUENCER_PT_adjust_color,
  1528. SEQUENCER_PT_adjust_sound,
  1529. SEQUENCER_PT_effect,
  1530. SEQUENCER_PT_scene,
  1531. SEQUENCER_PT_mask,
  1532. SEQUENCER_PT_time,
  1533. SEQUENCER_PT_source,
  1534. SEQUENCER_PT_modifiers,
  1535. SEQUENCER_PT_cache_settings,
  1536. SEQUENCER_PT_strip_cache,
  1537. SEQUENCER_PT_proxy_settings,
  1538. SEQUENCER_PT_strip_proxy,
  1539. SEQUENCER_PT_custom_props,
  1540. SEQUENCER_PT_preview,
  1541. SEQUENCER_PT_view,
  1542. SEQUENCER_PT_frame_overlay,
  1543. SEQUENCER_PT_view_safe_areas,
  1544. SEQUENCER_PT_view_safe_areas_center_cut,
  1545. SEQUENCER_PT_grease_pencil,
  1546. SEQUENCER_PT_grease_pencil_tools,
  1547. )
  1548. if __name__ == "__main__": # only for live edit.
  1549. from bpy.utils import register_class
  1550. for cls in classes:
  1551. register_class(cls)