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