menus are now global (like operators), so for eg, the info add menu and the 3D add...
[blender-staging.git] / release / scripts / ui / space_sequencer.py
1
2 import bpy
3
4 def act_strip(context):
5         try:            return context.scene.sequence_editor.active_strip
6         except: return None
7
8 # Header
9 class SEQUENCER_HT_header(bpy.types.Header):
10         __space_type__ = 'SEQUENCE_EDITOR'
11
12         def draw(self, context):
13                 layout = self.layout
14                 
15                 st = context.space_data
16
17                 row = layout.row(align=True)
18                 row.template_header()
19                 
20                 if context.area.show_menus:
21                         sub = row.row(align=True)
22                         sub.itemM("SEQUENCER_MT_view")
23                         
24                         row.itemS()
25                         
26                         if st.display_mode == 'SEQUENCER':
27                                 sub.itemM("SEQUENCER_MT_select")
28                                 sub.itemM("SEQUENCER_MT_marker")
29                                 sub.itemM("SEQUENCER_MT_add")
30                                 sub.itemM("SEQUENCER_MT_strip")
31
32                 layout.itemR(st, "display_mode", text="")
33
34                 if st.display_mode == 'SEQUENCER':
35                         layout.itemS()
36                         layout.itemO("sequencer.reload")
37                 else:
38                         layout.itemR(st, "display_channel", text="Channel")
39
40 class SEQUENCER_MT_view(bpy.types.Menu):
41         __label__ = "View"
42         
43         def draw(self, context):
44                 layout = self.layout
45                 
46                 st = context.space_data
47                 
48                 layout.column()
49                 
50                 """
51         uiBlock *block= uiBeginBlock(C, ar, "seq_viewmenu", UI_EMBOSSP);
52         short yco= 0, menuwidth=120;
53
54         if (sseq->mainb == SEQ_DRAW_SEQUENCE) {
55                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
56                                  "Play Back Animation "
57                                  "in all Sequence Areas|Alt A", 0, yco-=20,
58                                  menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
59         }
60         else {
61                 uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL,
62                                  "Grease Pencil...", 0, yco-=20,
63                                  menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
64                 uiDefMenuSep(block);
65
66                 uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
67                                  "Play Back Animation "
68                                  "in this window|Alt A", 0, yco-=20,
69                                  menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
70         }
71         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
72                          "Play Back Animation in all "
73                          "3D Views and Sequence Areas|Alt Shift A",
74                          0, yco-=20,
75                          menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
76
77                 """
78                 layout.itemS()
79                 layout.itemO("sequencer.view_all")
80                 layout.itemO("sequencer.view_selected")
81                 layout.itemS()
82                 layout.itemO("screen.screen_full_area", text="Toggle Full Screen")
83                 """
84         
85
86         /* Lock Time */
87         uiDefIconTextBut(block, BUTM, 1, (v2d->flag & V2D_VIEWSYNC_SCREEN_TIME)?ICON_CHECKBOX_HLT:ICON_CHECKBOX_DEHLT,
88                         "Lock Time to Other Windows|", 0, yco-=20,
89                         menuwidth, 19, NULL, 0.0, 0.0, 1, 5, "");
90
91         /* Draw time or frames.*/
92         uiDefMenuSep(block);
93                 """
94                 
95                 layout.itemR(st, "draw_frames")
96                 if st.display_mode == 'IMAGE':
97                         layout.itemR(st, "draw_safe_margin")
98                 if st.display_mode == 'WAVEFORM':
99                         layout.itemR(st, "seperate_color_preview")
100                 
101                 """
102         if(!sa->full) uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Maximize Window|Ctrl UpArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0,0, "");
103         else uiDefIconTextBut(block, BUTM, B_FULL, ICON_BLANK1, "Tile Window|Ctrl DownArrow", 0, yco-=20, menuwidth, 19, NULL, 0.0, 0.0, 0, 0, "");
104
105                 """
106
107 class SEQUENCER_MT_select(bpy.types.Menu):
108         __label__ = "Select"
109
110         def draw(self, context):
111                 layout = self.layout
112                 
113                 st = context.space_data
114                 
115                 layout.column()
116                 layout.item_enumO("sequencer.select_active_side", "side", 'LEFT', text="Strips to the Left")
117                 layout.item_enumO("sequencer.select_active_side", "side", 'RIGHT', text="Strips to the Right")
118                 layout.itemS()
119                 layout.item_enumO("sequencer.select_handles", "side", 'BOTH', text="Surrounding Handles")
120                 layout.item_enumO("sequencer.select_handles", "side", 'LEFT', text="Left Handle")
121                 layout.item_enumO("sequencer.select_handles", "side", 'RIGHT', text="Right Handle")
122                 layout.itemS()
123                 layout.itemO("sequencer.select_linked")
124                 layout.itemO("sequencer.select_all_toggle")
125                 layout.itemO("sequencer.select_inverse")
126
127 class SEQUENCER_MT_marker(bpy.types.Menu):
128         __label__ = "Marker (TODO)"
129
130         def draw(self, context):
131                 layout = self.layout
132                 
133                 st = context.space_data
134                 
135                 layout.column()
136                 layout.itemO("marker.add", text="Add Marker")
137                 layout.itemO("marker.duplicate", text="Duplicate Marker")
138                 layout.itemO("marker.move", text="Grab/Move Marker")
139                 layout.itemO("marker.delete", text="Delete Marker")
140                 layout.itemS()
141                 layout.itemL(text="ToDo: Name Marker")
142                 
143                 #layout.itemO("sequencer.sound_strip_add", text="Transform Markers") # toggle, will be rna - (sseq->flag & SEQ_MARKER_TRANS)
144
145 class SEQUENCER_MT_add(bpy.types.Menu):
146         __label__ = "Add"
147
148         def draw(self, context):
149                 layout = self.layout
150                 
151                 st = context.space_data
152                 
153                 layout.column()
154                 layout.itemO("sequencer.scene_strip_add", text="Scene")
155                 layout.itemO("sequencer.movie_strip_add", text="Movie")
156                 layout.itemO("sequencer.image_strip_add", text="Image")
157                 layout.itemO("sequencer.sound_strip_add", text="Sound")
158                 
159                 layout.itemM("SEQUENCER_MT_add_effect")
160
161 class SEQUENCER_MT_add_effect(bpy.types.Menu):
162         __label__ = "Effect Strip..."
163
164         def draw(self, context):
165                 layout = self.layout
166                 
167                 st = context.space_data
168                 
169                 layout.column()
170                 layout.item_enumO("sequencer.effect_strip_add", 'type', 'ADD')
171                 layout.item_enumO("sequencer.effect_strip_add", 'type', 'SUBTRACT')
172                 layout.item_enumO("sequencer.effect_strip_add", 'type', 'ALPHA_OVER')
173                 layout.item_enumO("sequencer.effect_strip_add", 'type', 'ALPHA_UNDER')
174                 layout.item_enumO("sequencer.effect_strip_add", 'type', 'GAMMA_CROSS')
175                 layout.item_enumO("sequencer.effect_strip_add", 'type', 'MULTIPLY')
176                 layout.item_enumO("sequencer.effect_strip_add", 'type', 'OVER_DROP')
177                 layout.item_enumO("sequencer.effect_strip_add", 'type', 'PLUGIN')
178                 layout.item_enumO("sequencer.effect_strip_add", 'type', 'WIPE')
179                 layout.item_enumO("sequencer.effect_strip_add", 'type', 'GLOW')
180                 layout.item_enumO("sequencer.effect_strip_add", 'type', 'TRANSFORM')
181                 layout.item_enumO("sequencer.effect_strip_add", 'type', 'COLOR')
182                 layout.item_enumO("sequencer.effect_strip_add", 'type', 'SPEED')
183
184 class SEQUENCER_MT_strip(bpy.types.Menu):
185         __label__ = "Strip"
186
187         def draw(self, context):
188                 layout = self.layout
189                 
190                 st = context.space_data
191                 
192                 layout.operator_context = 'INVOKE_REGION_WIN'
193                 
194                 layout.column()
195                 layout.item_enumO("tfm.transform", "mode", 'TRANSLATION', text="Grab/Move")
196                 layout.item_enumO("tfm.transform", "mode", 'TIME_EXTEND', text="Grab/Extend from frame")
197                 #  uiItemO(layout, NULL, 0, "sequencer.strip_snap"); // TODO - add this operator
198                 layout.itemS()
199                 
200                 layout.item_enumO("sequencer.cut", "type", 'HARD', text="Cut (hard) at frame")
201                 layout.item_enumO("sequencer.cut", "type", 'SOFT', text="Cut (soft) at frame")
202                 layout.itemO("sequencer.images_separate")
203                 layout.itemS()
204                 
205                 layout.itemO("sequencer.duplicate")
206                 layout.itemO("sequencer.delete")
207                 
208                 strip = act_strip(context)
209                 
210                 if strip:
211                         stype = strip.type
212                         
213                         if      stype=='EFFECT':
214                                 layout.itemS()
215                                 layout.itemO("sequencer.effect_change")
216                                 layout.itemO("sequencer.effect_reassign_inputs")
217                         elif stype=='IMAGE':
218                                 layout.itemS()
219                                 layout.itemO("sequencer.image_change")
220                         elif stype=='SCENE':
221                                 layout.itemS()
222                                 layout.itemO("sequencer.scene_change", text="Change Scene")
223                         elif stype=='MOVIE':
224                                 layout.itemS()
225                                 layout.itemO("sequencer.movie_change")
226                         
227                 layout.itemS()
228                 
229                 layout.itemO("sequencer.meta_make")
230                 layout.itemO("sequencer.meta_separate")
231                 
232                 #if (ed && (ed->metastack.first || (ed->act_seq && ed->act_seq->type == SEQ_META))) {
233                 #       uiItemS(layout);
234                 #       uiItemO(layout, NULL, 0, "sequencer.meta_toggle");
235                 #}
236                 
237                 layout.itemS()
238                 layout.itemO("sequencer.reload")
239                 layout.itemS()
240                 layout.itemO("sequencer.lock")
241                 layout.itemO("sequencer.unlock")
242                 layout.itemO("sequencer.mute")
243                 layout.itemO("sequencer.unmute")
244                 
245                 layout.item_booleanO("sequencer.mute", "unselected", 1, text="Mute Deselected Strips")
246
247                 layout.itemO("sequencer.snap")
248
249 # Panels
250 class SequencerButtonsPanel(bpy.types.Panel):
251         __space_type__ = 'SEQUENCE_EDITOR'
252         __region_type__ = 'UI'
253
254         def poll(self, context):
255                 return context.space_data.display_mode == 'SEQUENCER' and act_strip(context) != None
256                 
257 class SequencerButtonsPanel_Output(bpy.types.Panel):
258         __space_type__ = 'SEQUENCE_EDITOR'
259         __region_type__ = 'UI'
260
261         def poll(self, context):
262                 return context.space_data.display_mode != 'SEQUENCER'
263
264 class SEQUENCER_PT_edit(SequencerButtonsPanel):
265         __label__ = "Edit Strip"
266
267         def draw(self, context):
268                 layout = self.layout
269                 
270                 strip = act_strip(context)
271                 
272                 split = layout.split(percentage=0.3)
273                 split.itemL(text="Name:")
274                 split.itemR(strip, "name", text="")
275                 
276                 split = layout.split(percentage=0.3)
277                 split.itemL(text="Type:")
278                 split.itemR(strip, "type", text="")
279                 
280                 split = layout.split(percentage=0.3)
281                 split.itemL(text="Blend:")
282                 split.itemR(strip, "blend_mode", text="")
283                 
284                 row = layout.row()
285                 if strip.mute == True:
286                         row.itemR(strip, "mute", toggle=True, icon='ICON_RESTRICT_VIEW_ON', text="")
287                 elif strip.mute == False:
288                         row.itemR(strip, "mute", toggle=True, icon='ICON_RESTRICT_VIEW_OFF', text="")
289                 
290                 sub = row.row()
291                 sub.active = (not strip.mute)
292                 
293                 sub.itemR(strip, "blend_opacity", text="Opacity", slider=True)
294                 
295                 row = layout.row()
296                 row.itemR(strip, "lock")
297                 row.itemR(strip, "frame_locked", text="Frame Lock")
298                 
299                 col = layout.column()
300                 col.enabled = not strip.lock    
301                 col.itemR(strip, "channel")
302                 col.itemR(strip, "start_frame")
303                 col.itemR(strip, "length")
304                 
305                 col = layout.column(align=True)
306                 col.itemL(text="Offset:")
307                 col.itemR(strip, "start_offset", text="Start")
308                 col.itemR(strip, "end_offset", text="End")
309                 
310                 col = layout.column(align=True)
311                 col.itemL(text="Still:")
312                 col.itemR(strip, "start_still", text="Start")
313                 col.itemR(strip, "end_still", text="End")
314                 
315 class SEQUENCER_PT_effect(SequencerButtonsPanel):
316         __label__ = "Effect Strip"
317
318         def poll(self, context):
319                 if context.space_data.display_mode != 'SEQUENCER':
320                         return False
321                 
322                 strip = act_strip(context)
323                 if not strip:
324                         return False
325                 
326                 return strip.type in ('COLOR', 'WIPE', 'GLOW', 'SPEED', 'TRANSFORM')
327
328         def draw(self, context):
329                 layout = self.layout
330                 
331                 strip = act_strip(context)
332                 
333                 if strip.type == 'COLOR':
334                         layout.itemR(strip, "color")
335                         
336                 elif strip.type == 'WIPE':
337                         
338                         col = layout.column()
339                         col.itemR(strip, "transition_type")
340                         col.itemL(text="Direction:")
341                         col.row().itemR(strip, "direction", expand=True)
342                         
343                         col = layout.column()
344                         col.itemR(strip, "blur_width", slider=True)
345                         if strip.transition_type in ('SINGLE', 'DOUBLE'):
346                                 col.itemR(strip, "angle")
347                                 
348                 elif strip.type == 'GLOW':
349                         flow = layout.column_flow()
350                         flow.itemR(strip, "threshold", slider=True)
351                         flow.itemR(strip, "clamp", slider=True)
352                         flow.itemR(strip, "boost_factor")
353                         flow.itemR(strip, "blur_distance")
354                         
355                         row = layout.row()
356                         row.itemR(strip, "quality", slider=True)
357                         row.itemR(strip, "only_boost")
358                         
359                 elif strip.type == 'SPEED':
360                         layout.itemR(strip, "global_speed")
361                         
362                         flow = layout.column_flow()
363                         flow.itemR(strip, "curve_velocity")
364                         flow.itemR(strip, "curve_compress_y")
365                         flow.itemR(strip, "frame_blending")
366                         
367                 elif strip.type == 'TRANSFORM':
368                         
369                         col = layout.column()
370                         col.itemR(strip, "interpolation")
371                         col.itemR(strip, "translation_unit")
372                         
373                         col = layout.column(align=True)
374                         col.itemL(text="Position X:")
375                         col.itemR(strip, "translate_start_x", text="Start")
376                         col.itemR(strip, "translate_end_x", text="End")
377                         
378                         col = layout.column(align=True)
379                         col.itemL(text="Position Y:")
380                         col.itemR(strip, "translate_start_y", text="Start")
381                         col.itemR(strip, "translate_end_y", text="End")
382                         
383                         layout.itemS()
384                         
385                         col = layout.column(align=True)
386                         col.itemL(text="Scale X:")
387                         col.itemR(strip, "scale_start_x", text="Start")
388                         col.itemR(strip, "scale_end_x", text="End")
389                         
390                         col = layout.column(align=True)
391                         col.itemL(text="Scale Y:")
392                         col.itemR(strip, "scale_start_y", text="Start")
393                         col.itemR(strip, "scale_end_y", text="End")
394                         
395                         layout.itemS()
396                         
397                         col = layout.column(align=True)
398                         col.itemL(text="Rotation:")
399                         col.itemR(strip, "rotation_start", text="Start")
400                         col.itemR(strip, "rotation_end", text="End")
401
402 class SEQUENCER_PT_input(SequencerButtonsPanel):
403         __label__ = "Strip Input"
404         
405         def poll(self, context):
406                 if context.space_data.display_mode != 'SEQUENCER':
407                         return False
408                 
409                 strip = act_strip(context)
410                 if not strip:
411                         return False
412                 
413                 return strip.type in ('MOVIE', 'IMAGE')
414         
415         def draw(self, context):
416                 layout = self.layout
417                 
418                 strip = act_strip(context)
419                 
420                 split = layout.split(percentage=0.2)
421                 col = split.column()
422                 col.itemL(text="Path:")
423                 col = split.column()
424                 col.itemR(strip, "directory", text="")
425                 
426                 # Current element for the filename
427                 
428                 
429                 elem = strip.getStripElem(context.scene.current_frame)
430                 if elem:
431                         split = layout.split(percentage=0.2)
432                         col = split.column()
433                         col.itemL(text="File:")
434                         col = split.column()
435                         col.itemR(elem, "filename", text="") # strip.elements[0] could be a fallback
436                 
437                 layout.itemR(strip, "use_translation", text="Image Offset:")
438                 if strip.transform:
439                         col = layout.column(align=True)
440                         col.active = strip.use_translation
441                         col.itemR(strip.transform, "offset_x", text="X")
442                         col.itemR(strip.transform, "offset_y", text="Y")
443         
444                 layout.itemR(strip, "use_crop", text="Image Crop:")
445                 if strip.crop:
446                         col = layout.column(align=True)
447                         col.active = strip.use_crop
448                         col.itemR(strip.crop, "top")
449                         col.itemR(strip.crop, "left")
450                         col.itemR(strip.crop, "bottom")
451                         col.itemR(strip.crop, "right")
452                 
453                 col = layout.column(align=True)
454                 col.itemL(text="Trim Duration:")
455                 col.itemR(strip, "animation_start_offset", text="Start")
456                 col.itemR(strip, "animation_end_offset", text="End")
457
458 class SEQUENCER_PT_sound(SequencerButtonsPanel):
459         __label__ = "Sound"
460         
461         def poll(self, context):
462                 if context.space_data.display_mode != 'SEQUENCER':
463                         return False
464                 
465                 strip = act_strip(context)
466                 if not strip:
467                         return False
468                 
469                 return strip.type in ('SOUND', )
470         
471         def draw(self, context):
472                 layout = self.layout
473                 
474                 strip = act_strip(context)
475                 
476                 layout.template_ID(strip, "sound", new="sound.open")
477                 
478                 layout.itemS()
479                 layout.itemR(strip.sound, "filename", text="")
480                 
481                 row = layout.row()
482                 if strip.sound.packed_file:
483                         row.itemO("sound.unpack", icon='ICON_PACKAGE', text="Unpack")
484                 else:
485                         row.itemO("sound.pack", icon='ICON_UGLYPACKAGE', text="Pack")
486                 
487                 row.itemR(strip.sound, "caching")
488
489 class SEQUENCER_PT_filter(SequencerButtonsPanel):
490         __label__ = "Filter"
491         
492         def poll(self, context):
493                 if context.space_data.display_mode != 'SEQUENCER':
494                         return False
495                 
496                 strip = act_strip(context)
497                 if not strip:
498                         return False
499                 
500                 return strip.type in ('MOVIE', 'IMAGE', 'SCENE', 'META')
501         
502         def draw(self, context):
503                 layout = self.layout
504                 
505                 strip = act_strip(context)
506
507                 col = layout.column()
508                 col.itemL(text="Video:")
509                 col.itemR(strip, "strobe")
510                 col.itemR(strip, "de_interlace")
511                 
512                 col = layout.column()
513                 col.itemL(text="Colors:")
514                 col.itemR(strip, "multiply_colors", text="Multiply")
515                 col.itemR(strip, "premultiply")
516                 col.itemR(strip, "convert_float")
517
518                 col = layout.column()
519                 col.itemL(text="Flip:")
520                 col.itemR(strip, "flip_x", text="X")
521                 col.itemR(strip, "flip_y", text="Y")
522                 col.itemR(strip, "reverse_frames", text="Backwards")
523                 
524                 layout.itemR(strip, "use_color_balance")
525                 if strip.color_balance: # TODO - need to add this somehow
526                         row = layout.row()
527                         row.active = strip.use_color_balance
528                         col = row.column()
529                         col.itemR(strip.color_balance, "lift")
530                         col.itemR(strip.color_balance, "inverse_lift", text="Inverse")
531                         col = row.column()
532                         col.itemR(strip.color_balance, "gamma")
533                         col.itemR(strip.color_balance, "inverse_gamma", text="Inverse")
534                         col = row.column()
535                         col.itemR(strip.color_balance, "gain")
536                         col.itemR(strip.color_balance, "inverse_gain", text="Inverse")
537
538 class SEQUENCER_PT_proxy(SequencerButtonsPanel):
539         __label__ = "Proxy"
540         
541         def poll(self, context):
542                 if context.space_data.display_mode != 'SEQUENCER':
543                         return False
544                 
545                 strip = act_strip(context)
546                 if not strip:
547                         return False
548                 
549                 return strip.type in ('MOVIE', 'IMAGE', 'SCENE', 'META')
550         
551         def draw_header(self, context):
552                 strip = act_strip(context)
553                 
554                 self.layout.itemR(strip, "use_proxy", text="")
555
556         def draw(self, context):
557                 layout = self.layout
558                 
559                 strip = act_strip(context)
560                 
561                 flow = layout.column_flow()
562                 flow.itemR(strip, "proxy_custom_directory")
563                 if strip.proxy: # TODO - need to add this somehow
564                         flow.itemR(strip.proxy, "directory")
565                         flow.itemR(strip.proxy, "file")
566
567 class SEQUENCER_PT_view(SequencerButtonsPanel_Output):
568         __label__ = "View Settings"
569
570         def draw(self, context):
571                 layout = self.layout
572                 
573                 st = context.space_data
574
575                 col = layout.column()
576                 col.itemR(st, "draw_overexposed") # text="Zebra"
577                 col.itemR(st, "draw_safe_margin")
578
579 bpy.types.register(SEQUENCER_HT_header) # header/menu classes
580 bpy.types.register(SEQUENCER_MT_view)
581 bpy.types.register(SEQUENCER_MT_select)
582 bpy.types.register(SEQUENCER_MT_marker)
583 bpy.types.register(SEQUENCER_MT_add)
584 bpy.types.register(SEQUENCER_MT_add_effect)
585 bpy.types.register(SEQUENCER_MT_strip)
586
587 bpy.types.register(SEQUENCER_PT_edit) # sequencer panels
588 bpy.types.register(SEQUENCER_PT_effect)
589 bpy.types.register(SEQUENCER_PT_input)
590 bpy.types.register(SEQUENCER_PT_sound)
591 bpy.types.register(SEQUENCER_PT_filter)
592 bpy.types.register(SEQUENCER_PT_proxy)
593
594 bpy.types.register(SEQUENCER_PT_view) # view panels