fix for keying set rna path attribute and object select menu incorrect args to UI...
[blender.git] / release / scripts / ui / space_sequencer.py
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
19 # <pep8 compliant>
20 import bpy
21
22
23 def act_strip(context):
24     try:
25         return context.scene.sequence_editor.active_strip
26     except AttributeError:
27         return None
28
29
30 class SEQUENCER_HT_header(bpy.types.Header):
31     bl_space_type = 'SEQUENCE_EDITOR'
32
33     def draw(self, context):
34         layout = self.layout
35
36         st = context.space_data
37
38         row = layout.row(align=True)
39         row.template_header()
40
41         if context.area.show_menus:
42             sub = row.row(align=True)
43             sub.menu("SEQUENCER_MT_view")
44
45             row.separator()
46
47             if (st.view_type == 'SEQUENCER') or (st.view_type == 'SEQUENCER_PREVIEW'):
48                 sub.menu("SEQUENCER_MT_select")
49                 sub.menu("SEQUENCER_MT_marker")
50                 sub.menu("SEQUENCER_MT_add")
51                 sub.menu("SEQUENCER_MT_strip")
52
53         layout.prop(st, "view_type", text="")
54
55         if (st.view_type == 'PREVIEW') or (st.view_type == 'SEQUENCER_PREVIEW'):
56             layout.prop(st, "display_mode", text="")
57
58         if (st.view_type == 'SEQUENCER'):
59             row = layout.row(align=True)
60             row.operator("sequencer.copy", text="", icon='COPYDOWN')
61             row.operator("sequencer.paste", text="", icon='PASTEDOWN')
62
63             layout.separator()
64             layout.operator("sequencer.refresh_all")
65         elif (st.view_type == 'SEQUENCER_PREVIEW'):
66             layout.separator()
67             layout.operator("sequencer.refresh_all")
68             layout.prop(st, "display_channel", text="Channel")
69         else:
70             layout.prop(st, "display_channel", text="Channel")
71
72
73 class SEQUENCER_MT_view_toggle(bpy.types.Menu):
74     bl_label = "View Type"
75
76     def draw(self, context):
77         layout = self.layout
78
79         layout.operator("sequencer.view_toggle").type = 'SEQUENCER'
80         layout.operator("sequencer.view_toggle").type = 'PREVIEW'
81         layout.operator("sequencer.view_toggle").type = 'SEQUENCER_PREVIEW'
82
83
84 class SEQUENCER_MT_view(bpy.types.Menu):
85     bl_label = "View"
86
87     def draw(self, context):
88         layout = self.layout
89
90         st = context.space_data
91
92         layout.column()
93
94         """
95     uiBlock *block= uiBeginBlock(C, ar, "seq_viewmenu", UI_EMBOSSP);
96     short yco= 0, menuwidth=120;
97
98     if (sseq->mainb == SEQ_DRAW_SEQUENCE) {
99         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
100                  "Play Back Animation "
101                  "in all Sequence Areas|Alt A", 0, yco-=20,
102                  menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
103     }
104     else {
105         uiDefIconTextBut(block, BUTM, 1, ICON_MENU_PANEL,
106                  "Grease Pencil...", 0, yco-=20,
107                  menuwidth, 19, NULL, 0.0, 0.0, 1, 7, "");
108         uiDefMenuSep(block);
109
110         uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
111                  "Play Back Animation "
112                  "in this window|Alt A", 0, yco-=20,
113                  menuwidth, 19, NULL, 0.0, 0.0, 1, 1, "");
114     }
115     uiDefIconTextBut(block, BUTM, 1, ICON_BLANK1,
116              "Play Back Animation in all "
117              "3D Views and Sequence Areas|Alt Shift A",
118              0, yco-=20,
119              menuwidth, 19, NULL, 0.0, 0.0, 1, 2, "");
120
121         """
122         layout.separator()
123         if (st.view_type == 'SEQUENCER') or (st.view_type == 'SEQUENCER_PREVIEW'):
124             layout.operator("sequencer.view_all", text='View all Sequences')
125         if (st.view_type == 'PREVIEW') or (st.view_type == 'SEQUENCER_PREVIEW'):
126             layout.operator_context = 'INVOKE_REGION_PREVIEW'
127             layout.operator("sequencer.view_all_preview", text='Fit preview in window')
128             layout.operator_context = 'INVOKE_DEFAULT'
129         layout.operator("sequencer.view_selected")
130
131         layout.prop(st, "draw_frames")
132         layout.prop(st, "show_cframe_indicator")
133         if st.display_mode == 'IMAGE':
134             layout.prop(st, "draw_safe_margin")
135         if st.display_mode == 'WAVEFORM':
136             layout.prop(st, "separate_color_preview")
137
138         layout.separator()
139         layout.prop(st, "use_marker_sync")
140         layout.separator()
141
142         layout.operator("screen.area_dupli")
143         layout.operator("screen.screen_full_area")
144
145
146 class SEQUENCER_MT_select(bpy.types.Menu):
147     bl_label = "Select"
148
149     def draw(self, context):
150         layout = self.layout
151
152         layout.column()
153         layout.operator("sequencer.select_active_side", text="Strips to the Left").side = 'LEFT'
154         layout.operator("sequencer.select_active_side", text="Strips to the Right").side = 'RIGHT'
155         layout.separator()
156         layout.operator("sequencer.select_handles", text="Surrounding Handles").side = 'BOTH'
157         layout.operator("sequencer.select_handles", text="Left Handle").side = 'LEFT'
158         layout.operator("sequencer.select_handles", text="Right Handle").side = 'RIGHT'
159         layout.separator()
160         layout.operator("sequencer.select_linked")
161         layout.operator("sequencer.select_all_toggle")
162         layout.operator("sequencer.select_inverse")
163
164
165 class SEQUENCER_MT_marker(bpy.types.Menu):
166     bl_label = "Marker"
167
168     def draw(self, context):
169         layout = self.layout
170
171         layout.column()
172         layout.operator("marker.add", text="Add Marker")
173         layout.operator("marker.duplicate", text="Duplicate Marker")
174         layout.operator("marker.move", text="Grab/Move Marker")
175         layout.operator("marker.delete", text="Delete Marker")
176         layout.separator()
177         layout.label(text="ToDo: Name Marker")
178
179         #layout.operator("sequencer.sound_strip_add", text="Transform Markers") # toggle, will be rna - (sseq->flag & SEQ_MARKER_TRANS)
180
181
182 class SEQUENCER_MT_add(bpy.types.Menu):
183     bl_label = "Add"
184
185     def draw(self, context):
186         layout = self.layout
187         layout.operator_context = 'INVOKE_REGION_WIN'
188
189         layout.column()
190         layout.operator_menu_enum("sequencer.scene_strip_add", "scene", text="Scene...")
191         layout.operator("sequencer.movie_strip_add", text="Movie")
192         layout.operator("sequencer.image_strip_add", text="Image")
193         layout.operator("sequencer.sound_strip_add", text="Sound")
194
195         layout.menu("SEQUENCER_MT_add_effect")
196
197
198 class SEQUENCER_MT_add_effect(bpy.types.Menu):
199     bl_label = "Effect Strip..."
200
201     def draw(self, context):
202         layout = self.layout
203         layout.operator_context = 'INVOKE_REGION_WIN'
204
205         layout.column()
206         layout.operator("sequencer.effect_strip_add", text="Add").type = 'ADD'
207         layout.operator("sequencer.effect_strip_add", text="Subtract").type = 'SUBTRACT'
208         layout.operator("sequencer.effect_strip_add", text="Alpha Over").type = 'ALPHA_OVER'
209         layout.operator("sequencer.effect_strip_add", text="Alpha Under").type = 'ALPHA_UNDER'
210         layout.operator("sequencer.effect_strip_add", text="Cross").type = 'CROSS'
211         layout.operator("sequencer.effect_strip_add", text="Gamma Cross").type = 'GAMMA_CROSS'
212         layout.operator("sequencer.effect_strip_add", text="Multiply").type = 'MULTIPLY'
213         layout.operator("sequencer.effect_strip_add", text="Over Drop").type = 'OVER_DROP'
214         layout.operator("sequencer.effect_strip_add", text="Plugin").type = 'PLUGIN'
215         layout.operator("sequencer.effect_strip_add", text="Wipe").type = 'WIPE'
216         layout.operator("sequencer.effect_strip_add", text="Glow").type = 'GLOW'
217         layout.operator("sequencer.effect_strip_add", text="Transform").type = 'TRANSFORM'
218         layout.operator("sequencer.effect_strip_add", text="Color").type = 'COLOR'
219         layout.operator("sequencer.effect_strip_add", text="Speed Control").type = 'SPEED'
220
221
222 class SEQUENCER_MT_strip(bpy.types.Menu):
223     bl_label = "Strip"
224
225     def draw(self, context):
226         layout = self.layout
227
228         layout.operator_context = 'INVOKE_REGION_WIN'
229
230         layout.column()
231         layout.operator("transform.transform", text="Grab/Move").mode = 'TRANSLATION'
232         layout.operator("transform.transform", text="Grab/Extend from frame").mode = 'TIME_EXTEND'
233         #  uiItemO(layout, NULL, 0, "sequencer.strip_snap"); // TODO - add this operator
234         layout.separator()
235
236         layout.operator("sequencer.cut", text="Cut (hard) at frame").type = 'HARD'
237         layout.operator("sequencer.cut", text="Cut (soft) at frame").type = 'SOFT'
238         layout.operator("sequencer.images_separate")
239         layout.separator()
240
241         layout.operator("sequencer.duplicate")
242         layout.operator("sequencer.delete")
243
244         strip = act_strip(context)
245
246         if strip:
247             stype = strip.type
248
249             if  stype == 'EFFECT':
250                 layout.separator()
251                 layout.operator("sequencer.effect_change")
252                 layout.operator("sequencer.effect_reassign_inputs")
253             elif stype == 'IMAGE':
254                 layout.separator()
255                 # layout.operator("sequencer.image_change")
256                 layout.operator("sequencer.rendersize")
257             elif stype == 'SCENE':
258                 layout.separator()
259                 layout.operator("sequencer.scene_change", text="Change Scene")
260             elif stype == 'MOVIE':
261                 layout.separator()
262                 layout.operator("sequencer.movie_change")
263                 layout.operator("sequencer.rendersize")
264
265         layout.separator()
266
267         layout.operator("sequencer.meta_make")
268         layout.operator("sequencer.meta_separate")
269
270         #if (ed && (ed->metastack.first || (ed->act_seq && ed->act_seq->type == SEQ_META))) {
271         #       uiItemS(layout);
272         #       uiItemO(layout, NULL, 0, "sequencer.meta_toggle");
273         #}
274
275         layout.separator()
276         layout.operator("sequencer.reload")
277         layout.separator()
278         layout.operator("sequencer.lock")
279         layout.operator("sequencer.unlock")
280         layout.operator("sequencer.mute")
281         layout.operator("sequencer.unmute")
282
283         layout.operator("sequencer.mute", text="Mute Deselected Strips").unselected = True
284
285         layout.operator("sequencer.snap")
286
287         layout.operator_menu_enum("sequencer.swap", "side")
288
289
290 class SequencerButtonsPanel(bpy.types.Panel):
291     bl_space_type = 'SEQUENCE_EDITOR'
292     bl_region_type = 'UI'
293
294     def has_sequencer(self, context):
295         return (context.space_data.view_type == 'SEQUENCER') or (context.space_data.view_type == 'SEQUENCER_PREVIEW')
296
297     def poll(self, context):
298         return self.has_sequencer(context) and (act_strip(context) is not None)
299
300
301 class SequencerButtonsPanel_Output(bpy.types.Panel):
302     bl_space_type = 'SEQUENCE_EDITOR'
303     bl_region_type = 'UI'
304
305     def has_preview(self, context):
306         return (context.space_data.view_type == 'PREVIEW') or (context.space_data.view_type == 'SEQUENCER_PREVIEW')
307
308     def poll(self, context):
309         return self.has_preview(context)
310
311
312 class SEQUENCER_PT_edit(SequencerButtonsPanel):
313     bl_label = "Edit Strip"
314
315     def draw(self, context):
316         layout = self.layout
317         render = context.scene.render
318         strip = act_strip(context)
319
320         split = layout.split(percentage=0.3)
321         split.label(text="Name:")
322         split.prop(strip, "name", text="")
323
324         split = layout.split(percentage=0.3)
325         split.label(text="Type:")
326         split.prop(strip, "type", text="")
327
328         split = layout.split(percentage=0.3)
329         split.label(text="Blend:")
330         split.prop(strip, "blend_mode", text="")
331
332         row = layout.row()
333         if strip.mute == True:
334             row.prop(strip, "mute", toggle=True, icon='RESTRICT_VIEW_ON', text="")
335         elif strip.mute is False:
336             row.prop(strip, "mute", toggle=True, icon='RESTRICT_VIEW_OFF', text="")
337
338         sub = row.row()
339         sub.active = (not strip.mute)
340
341         sub.prop(strip, "blend_opacity", text="Opacity", slider=True)
342
343         row = layout.row()
344         row.prop(strip, "lock")
345         row.prop(strip, "frame_locked", text="Frame Lock")
346
347         col = layout.column()
348         col.enabled = not strip.lock
349         col.prop(strip, "channel")
350         col.prop(strip, "start_frame")
351         subrow = col.split(percentage=0.66)
352         subrow.prop(strip, "length")
353         subrow.label(text="%.2f sec" % (strip.length / (render.fps / render.fps_base)))
354
355         col = layout.column(align=True)
356         col.label(text="Offset:")
357         col.prop(strip, "start_offset", text="Start")
358         col.prop(strip, "end_offset", text="End")
359
360         col = layout.column(align=True)
361         col.label(text="Still:")
362         col.prop(strip, "start_still", text="Start")
363         col.prop(strip, "end_still", text="End")
364
365
366 class SEQUENCER_PT_preview(bpy.types.Panel):
367     bl_label = "Scene Preview/Render"
368     bl_space_type = 'SEQUENCE_EDITOR'
369     bl_region_type = 'UI'
370
371     def draw(self, context):
372         layout = self.layout
373         render = context.scene.render
374
375         col = layout.column()
376         col.prop(render, "use_sequencer_gl_preview", text="Open GL Preview")
377         col = layout.column()
378         col.active = render.use_sequencer_gl_preview
379         col.prop(render, "sequencer_gl_preview", text="")
380         
381         col = layout.column()
382         col.prop(render, "use_sequencer_gl_render", text="Open GL Render")
383         col = layout.column()
384         col.active = render.use_sequencer_gl_render
385         col.prop(render, "sequencer_gl_render", text="")
386
387
388 class SEQUENCER_PT_effect(SequencerButtonsPanel):
389     bl_label = "Effect Strip"
390
391     def poll(self, context):
392         if not self.has_sequencer(context):
393             return False
394
395         strip = act_strip(context)
396         if not strip:
397             return False
398
399         return strip.type in ('ADD', 'SUBTRACT', 'ALPHA_OVER', 'ALPHA_UNDER',
400                               'CROSS', 'GAMMA_CROSS', 'MULTIPLY', 'OVER_DROP',
401                               'PLUGIN',
402                               'WIPE', 'GLOW', 'TRANSFORM', 'COLOR', 'SPEED')
403
404     def draw(self, context):
405         layout = self.layout
406
407         strip = act_strip(context)
408
409         if strip.type == 'COLOR':
410             layout.prop(strip, "color")
411
412         elif strip.type == 'WIPE':
413
414             col = layout.column()
415             col.prop(strip, "transition_type")
416             col.label(text="Direction:")
417             col.row().prop(strip, "direction", expand=True)
418
419             col = layout.column()
420             col.prop(strip, "blur_width", slider=True)
421             if strip.transition_type in ('SINGLE', 'DOUBLE'):
422                 col.prop(strip, "angle")
423
424         elif strip.type == 'GLOW':
425             flow = layout.column_flow()
426             flow.prop(strip, "threshold", slider=True)
427             flow.prop(strip, "clamp", slider=True)
428             flow.prop(strip, "boost_factor")
429             flow.prop(strip, "blur_distance")
430
431             row = layout.row()
432             row.prop(strip, "quality", slider=True)
433             row.prop(strip, "only_boost")
434
435         elif strip.type == 'SPEED':
436             layout.prop(strip, "global_speed")
437
438             flow = layout.column_flow()
439             flow.prop(strip, "curve_velocity")
440             flow.prop(strip, "curve_compress_y")
441             flow.prop(strip, "frame_blending")
442
443         elif strip.type == 'TRANSFORM':
444             self.draw_panel_transform(strip)
445
446
447         col = layout.column(align=True)
448         if strip.type == 'SPEED':
449             col.prop(strip, "speed_fader", text="Speed fader")
450         elif strip.type in ('CROSS', 'GAMMA_CROSS', 'PLUGIN', 'WIPE'):
451                 col.prop(strip, "use_effect_default_fade", "Default fade")
452                 if not strip.use_effect_default_fade:
453                     col.prop(strip, "effect_fader", text="Effect fader")
454
455     def draw_panel_transform(self, strip):
456         layout = self.layout
457         col = layout.column()
458
459         col.prop(strip, "interpolation")
460         col.prop(strip, "translation_unit")
461         col = layout.column(align=True)
462         col.label(text="Position:")
463         col.prop(strip, "translate_start_x", text="X")
464         col.prop(strip, "translate_start_y", text="Y")
465
466         layout.separator()
467
468         col = layout.column(align=True)
469         col.prop(strip, "uniform_scale")
470         if (strip.uniform_scale):
471             col = layout.column(align=True)
472             col.prop(strip, "scale_start_x", text="Scale")
473         else:
474             col = layout.column(align=True)
475             col.label(text="Scale:")
476             col.prop(strip, "scale_start_x", text="X")
477             col.prop(strip, "scale_start_y", text="Y")
478
479         layout.separator()
480
481         col = layout.column(align=True)
482         col.label(text="Rotation:")
483         col.prop(strip, "rotation_start", text="Rotation")
484
485
486 class SEQUENCER_PT_input(SequencerButtonsPanel):
487     bl_label = "Strip Input"
488
489     def poll(self, context):
490         if not self.has_sequencer(context):
491             return False
492
493         strip = act_strip(context)
494         if not strip:
495             return False
496
497         return strip.type in ('MOVIE', 'IMAGE')
498
499     def draw_filename(self, context):
500         pass
501
502     def draw(self, context):
503         layout = self.layout
504
505         strip = act_strip(context)
506
507         self.draw_filename(context)
508
509         layout.prop(strip, "use_translation", text="Image Offset:")
510         if strip.transform:
511             col = layout.column(align=True)
512             col.active = strip.use_translation
513             col.prop(strip.transform, "offset_x", text="X")
514             col.prop(strip.transform, "offset_y", text="Y")
515
516         layout.prop(strip, "use_crop", text="Image Crop:")
517         if strip.crop:
518             col = layout.column(align=True)
519             col.active = strip.use_crop
520             col.prop(strip.crop, "top")
521             col.prop(strip.crop, "left")
522             col.prop(strip.crop, "bottom")
523             col.prop(strip.crop, "right")
524
525         col = layout.column(align=True)
526         col.label(text="Trim Duration:")
527         col.prop(strip, "animation_start_offset", text="Start")
528         col.prop(strip, "animation_end_offset", text="End")
529
530
531 class SEQUENCER_PT_input_movie(SEQUENCER_PT_input):
532     bl_label = "Strip Input"
533
534     def poll(self, context):
535         if not self.has_sequencer(context):
536             return False
537
538         strip = act_strip(context)
539         if not strip:
540             return False
541
542         return strip.type == 'MOVIE'
543
544     def draw_filename(self, context):
545         layout = self.layout
546
547         strip = act_strip(context)
548
549         split = layout.split(percentage=0.2)
550         col = split.column()
551         col.label(text="Path:")
552         col = split.column()
553         col.prop(strip, "filepath", text="")
554
555
556 class SEQUENCER_PT_input_image(SEQUENCER_PT_input):
557     bl_label = "Strip Input"
558
559     def poll(self, context):
560         if not self.has_sequencer(context):
561             return False
562
563         strip = act_strip(context)
564         if not strip:
565             return False
566
567         return strip.type == 'IMAGE'
568
569     def draw_filename(self, context):
570         layout = self.layout
571
572         strip = act_strip(context)
573
574         split = layout.split(percentage=0.2)
575         col = split.column()
576         col.label(text="Path:")
577         col = split.column()
578         col.prop(strip, "directory", text="")
579
580         # Current element for the filename
581
582         elem = strip.getStripElem(context.scene.current_frame)
583         if elem:
584             split = layout.split(percentage=0.2)
585             col = split.column()
586             col.label(text="File:")
587             col = split.column()
588             col.prop(elem, "filename", text="") # strip.elements[0] could be a fallback
589
590
591 class SEQUENCER_PT_sound(SequencerButtonsPanel):
592     bl_label = "Sound"
593
594     def poll(self, context):
595         if not self.has_sequencer(context):
596             return False
597
598         strip = act_strip(context)
599         if not strip:
600             return False
601
602         return (strip.type == 'SOUND')
603
604     def draw(self, context):
605         layout = self.layout
606
607         strip = act_strip(context)
608
609         layout.template_ID(strip, "sound", open="sound.open")
610
611         layout.separator()
612         layout.prop(strip, "filepath", text="")
613
614         row = layout.row()
615         if strip.sound.packed_file:
616             row.operator("sound.unpack", icon='PACKAGE', text="Unpack")
617         else:
618             row.operator("sound.pack", icon='UGLYPACKAGE', text="Pack")
619
620         row.prop(strip.sound, "caching")
621
622         layout.prop(strip, "volume")
623
624
625 class SEQUENCER_PT_scene(SequencerButtonsPanel):
626     bl_label = "Scene"
627
628     def poll(self, context):
629         if not self.has_sequencer(context):
630             return False
631
632         strip = act_strip(context)
633         if not strip:
634             return False
635
636         return (strip.type == 'SCENE')
637
638     def draw(self, context):
639         layout = self.layout
640
641         strip = act_strip(context)
642
643         layout.template_ID(strip, "scene")
644
645         layout.label(text="Camera Override")
646         layout.template_ID(strip, "scene_camera")
647
648
649 class SEQUENCER_PT_filter(SequencerButtonsPanel):
650     bl_label = "Filter"
651
652     def poll(self, context):
653         if not self.has_sequencer(context):
654             return False
655
656         strip = act_strip(context)
657         if not strip:
658             return False
659
660         return strip.type in ('MOVIE', 'IMAGE', 'SCENE', 'META')
661
662     def draw(self, context):
663         layout = self.layout
664
665         strip = act_strip(context)
666
667         col = layout.column()
668         col.label(text="Video:")
669         col.prop(strip, "strobe")
670         col.prop(strip, "de_interlace")
671
672         col = layout.column()
673         col.label(text="Colors:")
674         col.prop(strip, "multiply_colors", text="Multiply")
675         col.prop(strip, "premultiply")
676         col.prop(strip, "convert_float")
677
678         col = layout.column()
679         col.label(text="Flip:")
680         col.prop(strip, "flip_x", text="X")
681         col.prop(strip, "flip_y", text="Y")
682         col.prop(strip, "reverse_frames", text="Backwards")
683
684         layout.prop(strip, "use_color_balance")
685         if strip.color_balance: # TODO - need to add this somehow
686             row = layout.row()
687             row.active = strip.use_color_balance
688             col = row.column()
689             col.template_color_wheel(strip.color_balance, "lift", value_slider=False)
690             col.row().prop(strip.color_balance, "lift")
691             col.prop(strip.color_balance, "inverse_lift", text="Inverse")
692             col = row.column()
693             col.template_color_wheel(strip.color_balance, "gamma", value_slider=False)
694             col.row().prop(strip.color_balance, "gamma")
695             col.prop(strip.color_balance, "inverse_gamma", text="Inverse")
696             col = row.column()
697             col.template_color_wheel(strip.color_balance, "gain", value_slider=False)
698             col.row().prop(strip.color_balance, "gain")
699             col.prop(strip.color_balance, "inverse_gain", text="Inverse")
700
701
702 class SEQUENCER_PT_proxy(SequencerButtonsPanel):
703     bl_label = "Proxy"
704
705     def poll(self, context):
706         if not self.has_sequencer(context):
707             return False
708
709         strip = act_strip(context)
710         if not strip:
711             return False
712
713         return strip.type in ('MOVIE', 'IMAGE', 'SCENE', 'META')
714
715     def draw_header(self, context):
716         strip = act_strip(context)
717
718         self.layout.prop(strip, "use_proxy", text="")
719
720     def draw(self, context):
721         layout = self.layout
722
723         strip = act_strip(context)
724
725         flow = layout.column_flow()
726         flow.prop(strip, "proxy_custom_directory")
727         if strip.proxy: # TODO - need to add this somehow
728             flow.prop(strip.proxy, "directory")
729             flow.prop(strip.proxy, "file")
730
731
732 class SEQUENCER_PT_view(SequencerButtonsPanel_Output):
733     bl_label = "View Settings"
734
735     def draw(self, context):
736         layout = self.layout
737
738         st = context.space_data
739
740         col = layout.column()
741         col.prop(st, "draw_overexposed") # text="Zebra"
742         col.prop(st, "draw_safe_margin")
743
744
745 classes = [
746     SEQUENCER_HT_header, # header/menu classes
747     SEQUENCER_MT_view,
748     SEQUENCER_MT_view_toggle,
749     SEQUENCER_MT_select,
750     SEQUENCER_MT_marker,
751     SEQUENCER_MT_add,
752     SEQUENCER_MT_add_effect,
753     SEQUENCER_MT_strip,
754
755     SEQUENCER_PT_edit, # sequencer panels
756     SEQUENCER_PT_preview,
757     SEQUENCER_PT_effect,
758     SEQUENCER_PT_input_movie,
759     SEQUENCER_PT_input_image,
760     SEQUENCER_PT_sound,
761     SEQUENCER_PT_scene,
762     SEQUENCER_PT_filter,
763     SEQUENCER_PT_proxy,
764
765     SEQUENCER_PT_view] # view panels
766
767
768 def register():
769     register = bpy.types.register
770     for cls in classes:
771         register(cls)
772
773
774 def unregister():
775     unregister = bpy.types.unregister
776     for cls in classes:
777         unregister(cls)
778
779 if __name__ == "__main__":
780     register()