add mask buttons into the image space
[blender.git] / release / scripts / startup / bl_ui / space_clip.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-80 compliant>
20
21 import bpy
22 from bpy.types import Panel, Header, Menu
23
24
25 class CLIP_HT_header(Header):
26     bl_space_type = 'CLIP_EDITOR'
27
28     def _draw_tracking(self, context):
29         layout = self.layout
30
31         sc = context.space_data
32         clip = sc.clip
33
34         row = layout.row(align=True)
35         row.template_header()
36
37         if context.area.show_menus:
38             sub = row.row(align=True)
39             sub.menu("CLIP_MT_view")
40
41             if sc.view == 'CLIP':
42                 if clip:
43                     sub.menu("CLIP_MT_select")
44                     sub.menu("CLIP_MT_clip")
45                     sub.menu("CLIP_MT_track")
46                     sub.menu("CLIP_MT_reconstruction")
47                 else:
48                     sub.menu("CLIP_MT_clip")
49
50         row = layout.row()
51         row.template_ID(sc, "clip", open="clip.open")
52
53         if clip:
54             tracking = clip.tracking
55             active_object = tracking.objects.active
56
57             if sc.view == 'CLIP':
58                 layout.prop(sc, "mode", text="")
59                 layout.prop(sc, "view", text="", expand=True)
60                 layout.prop(sc, "pivot_point", text="", icon_only=True)
61
62                 r = active_object.reconstruction
63
64                 if r.is_valid and sc.view == 'CLIP':
65                     layout.label(text="Solve error: %.4f" %
66                                  (r.average_error))
67             elif sc.view == 'GRAPH':
68                 layout.prop(sc, "view", text="", expand=True)
69
70                 row = layout.row(align=True)
71                 row.prop(sc, "show_graph_only_selected", text="")
72                 row.prop(sc, "show_graph_hidden", text="")
73
74                 row = layout.row(align=True)
75
76                 if sc.show_filters:
77                     row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_DOWN',
78                              text="Filters")
79
80                     sub = row.column()
81                     sub.active = clip.tracking.reconstruction.is_valid
82                     sub.prop(sc, "show_graph_frames", icon='SEQUENCE', text="")
83
84                     row.prop(sc, "show_graph_tracks", icon='ANIM', text="")
85                 else:
86                     row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_RIGHT',
87                              text="Filters")
88             elif sc.view == 'DOPESHEET':
89                 dopesheet = tracking.dopesheet
90                 layout.prop(sc, "view", text="", expand=True)
91
92                 row = layout.row(align=True)
93                 row.prop(dopesheet, "show_only_selected", text="")
94                 row.prop(dopesheet, "show_hidden", text="")
95
96                 row = layout.row(align=True)
97                 row.prop(dopesheet, "sort_method", text="")
98                 row.prop(dopesheet, "use_invert_sort",
99                          text="Invert", toggle=True)
100         else:
101             layout.prop(sc, "view", text="", expand=True)
102
103     def _draw_masking(self, context):
104         layout = self.layout
105
106         toolsettings = context.tool_settings
107         sc = context.space_data
108         clip = sc.clip
109
110         row = layout.row(align=True)
111         row.template_header()
112
113         if context.area.show_menus:
114             sub = row.row(align=True)
115             sub.menu("CLIP_MT_view")
116
117             if clip:
118                 sub.menu("MASK_MT_select")
119                 sub.menu("CLIP_MT_clip")  # XXX - remove?
120                 sub.menu("MASK_MT_mask")
121             else:
122                 sub.menu("CLIP_MT_clip")  # XXX - remove?
123
124         row = layout.row()
125         row.template_ID(sc, "clip", open="clip.open")
126
127         layout.prop(sc, "mode", text="")
128
129         row = layout.row()
130         row.template_ID(sc, "mask", new="mask.new")
131
132         layout.prop(sc, "pivot_point", text="", icon_only=True)
133
134         row = layout.row(align=True)
135         row.prop(toolsettings, "use_proportional_edit_mask",
136                  text="", icon_only=True)
137         if toolsettings.use_proportional_edit_mask:
138             row.prop(toolsettings, "proportional_edit_falloff",
139                      text="", icon_only=True)
140
141     def draw(self, context):
142         layout = self.layout
143
144         sc = context.space_data
145
146         if sc.mode in {'TRACKING', 'RECONSTRUCTION', 'DISTORTION'}:
147             self._draw_tracking(context)
148         else:
149             self._draw_masking(context)
150
151         layout.template_running_jobs()
152
153
154 class CLIP_PT_clip_view_panel:
155
156     @classmethod
157     def poll(cls, context):
158         sc = context.space_data
159         clip = sc.clip
160
161         return clip and sc.view == 'CLIP'
162
163
164 class CLIP_PT_tracking_panel:
165
166     @classmethod
167     def poll(cls, context):
168         sc = context.space_data
169         clip = sc.clip
170
171         return clip and sc.mode == 'TRACKING' and sc.view == 'CLIP'
172
173
174 class CLIP_PT_reconstruction_panel:
175
176     @classmethod
177     def poll(cls, context):
178         sc = context.space_data
179         clip = sc.clip
180
181         return clip and sc.mode == 'RECONSTRUCTION' and sc.view == 'CLIP'
182
183
184 class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel):
185     bl_space_type = 'CLIP_EDITOR'
186     bl_region_type = 'TOOLS'
187     bl_label = "Marker"
188
189     def draw(self, context):
190         sc = context.space_data
191         clip = sc.clip
192         settings = clip.tracking.settings
193         layout = self.layout
194
195         col = layout.column(align=True)
196         col.operator("clip.add_marker_move")
197         col.operator("clip.detect_features")
198         col.operator("clip.delete_track")
199
200         box = layout.box()
201         row = box.row(align=True)
202         row.prop(settings, "show_default_expanded", text="", emboss=False)
203         row.label(text="Tracking Settings")
204
205         if settings.show_default_expanded:
206             col = box.column()
207             row = col.row(align=True)
208             label = CLIP_MT_tracking_settings_presets.bl_label
209             row.menu('CLIP_MT_tracking_settings_presets', text=label)
210             row.operator("clip.tracking_settings_preset_add",
211                          text="", icon='ZOOMIN')
212             props = row.operator("clip.tracking_settings_preset_add",
213                                  text="", icon='ZOOMOUT')
214             props.remove_active = True
215
216             col.separator()
217
218             row = col.row(align=True)
219             row.prop(settings, "use_default_red_channel",
220                      text="R", toggle=True)
221             row.prop(settings, "use_default_green_channel",
222                      text="G", toggle=True)
223             row.prop(settings, "use_default_blue_channel",
224                      text="B", toggle=True)
225
226             col.separator()
227
228             sub = col.column(align=True)
229             sub.prop(settings, "default_pattern_size")
230             sub.prop(settings, "default_search_size")
231
232             col.label(text="Tracker:")
233             col.prop(settings, "default_motion_model")
234             col.prop(settings, "default_use_brute")
235             col.prop(settings, "default_use_normalization")
236             col.prop(settings, "default_use_mask")
237             col.prop(settings, "default_correlation_min")
238
239             col.separator()
240
241             sub = col.column(align=True)
242             sub.prop(settings, "default_frames_limit")
243             sub.prop(settings, "default_margin")
244
245             col.label(text="Match:")
246             col.prop(settings, "default_pattern_match", text="")
247
248             col.separator()
249             col.operator("clip.track_settings_as_default",
250                          text="Copy From Active Track")
251
252
253 class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
254     bl_space_type = 'CLIP_EDITOR'
255     bl_region_type = 'TOOLS'
256     bl_label = "Track"
257
258     def draw(self, context):
259         layout = self.layout
260
261         row = layout.row(align=True)
262
263         props = row.operator("clip.track_markers", text="", icon='FRAME_PREV')
264         props.backwards = True
265         props.sequence = False
266         props = row.operator("clip.track_markers", text="",
267                              icon='PLAY_REVERSE')
268         props.backwards = True
269         props.sequence = True
270         props = row.operator("clip.track_markers", text="", icon='PLAY')
271         props.backwards = False
272         props.sequence = True
273         props = row.operator("clip.track_markers", text="", icon='FRAME_NEXT')
274         props.backwards = False
275         props.sequence = False
276
277         col = layout.column(align=True)
278         props = col.operator("clip.clear_track_path", text="Clear After")
279         props.action = 'REMAINED'
280
281         props = col.operator("clip.clear_track_path", text="Clear Before")
282         props.action = 'UPTO'
283         col.operator("clip.clear_track_path", text="Clear").action = 'ALL'
284
285         layout.operator("clip.join_tracks", text="Join")
286
287
288 class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel):
289     bl_space_type = 'CLIP_EDITOR'
290     bl_region_type = 'TOOLS'
291     bl_label = "Solve"
292
293     def draw(self, context):
294         layout = self.layout
295         clip = context.space_data.clip
296         tracking = clip.tracking
297         settings = tracking.settings
298         tracking_object = tracking.objects.active
299
300         col = layout.column(align=True)
301
302         col.operator("clip.solve_camera",
303                      text="Camera Motion" if tracking_object.is_camera
304                      else "Object Motion")
305         col.operator("clip.clear_solution")
306
307         col = layout.column()
308         col.prop(settings, "use_tripod_solver")
309
310         col = layout.column(align=True)
311         col.active = not settings.use_tripod_solver
312         col.prop(settings, "keyframe_a")
313         col.prop(settings, "keyframe_b")
314
315         col = layout.column(align=True)
316         col.active = (tracking_object.is_camera and
317                       not settings.use_tripod_solver)
318         col.label(text="Refine:")
319         col.prop(settings, "refine_intrinsics", text="")
320
321
322 class CLIP_PT_tools_cleanup(CLIP_PT_tracking_panel, Panel):
323     bl_space_type = 'CLIP_EDITOR'
324     bl_region_type = 'TOOLS'
325     bl_label = "Clean up"
326
327     def draw(self, context):
328         layout = self.layout
329         clip = context.space_data.clip
330         settings = clip.tracking.settings
331
332         layout.operator("clip.clean_tracks")
333
334         layout.prop(settings, "clean_frames", text="Frames")
335         layout.prop(settings, "clean_error", text="Error")
336         layout.prop(settings, "clean_action", text="")
337
338
339 class CLIP_PT_tools_geometry(CLIP_PT_reconstruction_panel, Panel):
340     bl_space_type = 'CLIP_EDITOR'
341     bl_region_type = 'TOOLS'
342     bl_label = "Geometry"
343
344     def draw(self, context):
345         layout = self.layout
346
347         layout.operator("clip.bundles_to_mesh")
348         layout.operator("clip.track_to_empty")
349
350
351 class CLIP_PT_tools_orientation(CLIP_PT_reconstruction_panel, Panel):
352     bl_space_type = 'CLIP_EDITOR'
353     bl_region_type = 'TOOLS'
354     bl_label = "Orientation"
355
356     def draw(self, context):
357         sc = context.space_data
358         layout = self.layout
359         settings = sc.clip.tracking.settings
360
361         col = layout.column(align=True)
362         row = col.row()
363         props = row.operator("clip.set_plane", text="Floor")
364         props.plane = 'FLOOR'
365         props = row.operator("clip.set_plane", text="Wall")
366         props.plane = 'WALL'
367         col.operator("clip.set_origin")
368
369         row = col.row()
370         row.operator("clip.set_axis", text="Set X Axis").axis = 'X'
371         row.operator("clip.set_axis", text="Set Y Axis").axis = 'Y'
372
373         layout.separator()
374
375         col = layout.column()
376         col.operator("clip.set_scale")
377         col.prop(settings, "distance")
378
379
380 class CLIP_PT_tools_object(CLIP_PT_reconstruction_panel, Panel):
381     bl_space_type = 'CLIP_EDITOR'
382     bl_region_type = 'TOOLS'
383     bl_label = "Object"
384
385     @classmethod
386     def poll(cls, context):
387         if CLIP_PT_reconstruction_panel.poll(context):
388             sc = context.space_data
389             clip = sc.clip
390
391             tracking_object = clip.tracking.objects.active
392
393             return not tracking_object.is_camera
394
395         return False
396
397     def draw(self, context):
398         layout = self.layout
399
400         sc = context.space_data
401         clip = sc.clip
402         tracking_object = clip.tracking.objects.active
403         settings = sc.clip.tracking.settings
404
405         col = layout.column()
406
407         col.prop(tracking_object, "scale")
408
409         col.separator()
410
411         col.operator("clip.set_solution_scale", text="Set Scale")
412         col.prop(settings, "object_distance")
413
414
415 class CLIP_PT_tools_grease_pencil(Panel):
416     bl_space_type = 'CLIP_EDITOR'
417     bl_region_type = 'TOOLS'
418     bl_label = "Grease Pencil"
419
420     @classmethod
421     def poll(cls, context):
422         sc = context.space_data
423         clip = sc.clip
424
425         if not clip:
426             return False
427
428         if sc.mode == 'DISTORTION':
429             return sc.view == 'CLIP'
430         elif sc.mode == 'MASK':
431             return True
432
433         return False
434
435     def draw(self, context):
436         layout = self.layout
437
438         col = layout.column(align=True)
439
440         row = col.row(align=True)
441         row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
442         row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
443
444         row = col.row(align=True)
445         row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
446         row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
447
448         row = col.row()
449         row.prop(context.tool_settings, "use_grease_pencil_sessions")
450
451
452 class CLIP_PT_objects(CLIP_PT_clip_view_panel, Panel):
453     bl_space_type = 'CLIP_EDITOR'
454     bl_region_type = 'UI'
455     bl_label = "Objects"
456     bl_options = {'DEFAULT_CLOSED'}
457
458     def draw(self, context):
459         layout = self.layout
460
461         sc = context.space_data
462         tracking = sc.clip.tracking
463
464         row = layout.row()
465         row.template_list(tracking, "objects",
466                           tracking, "active_object_index", rows=3)
467
468         sub = row.column(align=True)
469
470         sub.operator("clip.tracking_object_new", icon='ZOOMIN', text="")
471         sub.operator("clip.tracking_object_remove", icon='ZOOMOUT', text="")
472
473         active = tracking.objects.active
474         if active:
475             layout.prop(active, "name")
476
477
478 class CLIP_PT_track(CLIP_PT_tracking_panel, Panel):
479     bl_space_type = 'CLIP_EDITOR'
480     bl_region_type = 'UI'
481     bl_label = "Track"
482
483     def draw(self, context):
484         layout = self.layout
485         sc = context.space_data
486         clip = context.space_data.clip
487         act_track = clip.tracking.tracks.active
488
489         if not act_track:
490             layout.active = False
491             layout.label(text="No active track")
492             return
493
494         row = layout.row()
495         row.prop(act_track, "name", text="")
496
497         sub = row.row(align=True)
498
499         sub.template_marker(sc, "clip", sc.clip_user, act_track, True)
500
501         icon = 'LOCKED' if act_track.lock else 'UNLOCKED'
502         sub.prop(act_track, "lock", text="", icon=icon)
503
504         layout.template_track(sc, "scopes")
505
506         row = layout.row(align=True)
507         sub = row.row()
508         sub.prop(act_track, "use_red_channel", text="R", toggle=True)
509         sub.prop(act_track, "use_green_channel", text="G", toggle=True)
510         sub.prop(act_track, "use_blue_channel", text="B", toggle=True)
511
512         row.separator()
513
514         sub = row.row()
515         sub.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True)
516
517         row.separator()
518         sub = row.row()
519         sub.prop(act_track, "use_alpha_preview",
520                  text="", toggle=True, icon='IMAGE_ALPHA')
521
522         layout.separator()
523
524         row = layout.row(align=True)
525         label = bpy.types.CLIP_MT_track_color_presets.bl_label
526         row.menu('CLIP_MT_track_color_presets', text=label)
527         row.menu('CLIP_MT_track_color_specials', text="", icon='DOWNARROW_HLT')
528         row.operator("clip.track_color_preset_add", text="", icon='ZOOMIN')
529         props = row.operator("clip.track_color_preset_add",
530                              text="", icon='ZOOMOUT')
531         props.remove_active = True
532
533         row = layout.row()
534         row.prop(act_track, "use_custom_color")
535         if act_track.use_custom_color:
536             row.prop(act_track, "color", text="")
537
538         if act_track.has_bundle:
539             label_text = "Average Error: %.4f" % (act_track.average_error)
540             layout.label(text=label_text)
541
542
543 class CLIP_PT_track_settings(CLIP_PT_tracking_panel, Panel):
544     bl_space_type = 'CLIP_EDITOR'
545     bl_region_type = 'UI'
546     bl_label = "Tracking Settings"
547     bl_options = {'DEFAULT_CLOSED'}
548
549     def draw(self, context):
550         layout = self.layout
551         clip = context.space_data.clip
552         settings = clip.tracking.settings
553
554         col = layout.column()
555
556         active = clip.tracking.tracks.active
557         if active:
558             col.prop(active, "motion_model")
559             col.prop(active, "use_brute")
560             col.prop(active, "use_normalization")
561             col.prop(active, "use_mask")
562             col.prop(active, "correlation_min")
563
564             col.separator()
565             col.prop(active, "frames_limit")
566             col.prop(active, "margin")
567             col.prop(active, "pattern_match", text="Match")
568
569         col.prop(settings, "speed")
570
571
572 class CLIP_PT_tracking_camera(Panel):
573     bl_space_type = 'CLIP_EDITOR'
574     bl_region_type = 'UI'
575     bl_label = "Camera Data"
576     bl_options = {'DEFAULT_CLOSED'}
577
578     @classmethod
579     def poll(cls, context):
580         if CLIP_PT_clip_view_panel.poll(context):
581             sc = context.space_data
582
583             return sc.mode in {'TRACKING', 'DISTORTION'} and sc.clip
584
585         return False
586
587     def draw(self, context):
588         layout = self.layout
589
590         sc = context.space_data
591         clip = sc.clip
592
593         row = layout.row(align=True)
594         label = bpy.types.CLIP_MT_camera_presets.bl_label
595         row.menu('CLIP_MT_camera_presets', text=label)
596         row.operator("clip.camera_preset_add", text="", icon='ZOOMIN')
597         props = row.operator("clip.camera_preset_add", text="", icon='ZOOMOUT')
598         props.remove_active = True
599
600         row = layout.row(align=True)
601         sub = row.split(percentage=0.65)
602         if clip.tracking.camera.units == 'MILLIMETERS':
603             sub.prop(clip.tracking.camera, "focal_length")
604         else:
605             sub.prop(clip.tracking.camera, "focal_length_pixels")
606         sub.prop(clip.tracking.camera, "units", text="")
607
608         col = layout.column(align=True)
609         col.label(text="Sensor:")
610         col.prop(clip.tracking.camera, "sensor_width", text="Width")
611         col.prop(clip.tracking.camera, "pixel_aspect")
612
613         col = layout.column()
614         col.label(text="Optical Center:")
615         row = col.row()
616         row.prop(clip.tracking.camera, "principal", text="")
617         col.operator("clip.set_center_principal", text="Center")
618
619         col = layout.column(align=True)
620         col.label(text="Lens Distortion:")
621         col.prop(clip.tracking.camera, "k1")
622         col.prop(clip.tracking.camera, "k2")
623         col.prop(clip.tracking.camera, "k3")
624
625
626 class CLIP_PT_display(CLIP_PT_clip_view_panel, Panel):
627     bl_space_type = 'CLIP_EDITOR'
628     bl_region_type = 'UI'
629     bl_label = "Display"
630
631     def draw(self, context):
632         layout = self.layout
633         sc = context.space_data
634
635         row = layout.row(align=True)
636         sub = row.row()
637         sub.prop(sc, "show_red_channel", text="R", toggle=True)
638         sub.prop(sc, "show_green_channel", text="G", toggle=True)
639         sub.prop(sc, "show_blue_channel", text="B", toggle=True)
640
641         row.separator()
642
643         sub = row.row()
644         sub.prop(sc, "use_grayscale_preview", text="B/W", toggle=True)
645
646         col = layout.column(align=True)
647
648         col.prop(sc, "show_disabled", "Disabled Tracks")
649         col.prop(sc, "show_names", text="Names and Status")
650         col.prop(sc, "show_bundles", text="3D Markers")
651
652         col.prop(sc, "use_mute_footage", text="Mute Footage")
653         col.prop(sc, "lock_selection")
654
655         if sc.view == 'GRAPH':
656             col.prop(sc, "lock_time_cursor")
657
658         if sc.mode == 'DISTORTION':
659             col.prop(sc, "show_grid", text="Grid")
660             col.prop(sc, "use_manual_calibration")
661         elif sc.mode == 'RECONSTRUCTION':
662             col.prop(sc, "show_stable", text="Stable")
663
664         clip = sc.clip
665         if clip:
666             col.label(text="Display Aspect Ratio:")
667             row = col.row()
668             row.prop(clip, "display_aspect", text="")
669
670
671 class CLIP_PT_marker_display(CLIP_PT_clip_view_panel, Panel):
672     bl_space_type = 'CLIP_EDITOR'
673     bl_region_type = 'UI'
674     bl_label = "Marker Display"
675
676     @classmethod
677     def poll(cls, context):
678         sc = context.space_data
679
680         return sc.mode != 'MASK'
681
682     def draw(self, context):
683         layout = self.layout
684         sc = context.space_data
685
686         col = layout.column(align=True)
687
688         row = col.row()
689         row.prop(sc, "show_marker_pattern", text="Pattern")
690         row.prop(sc, "show_marker_search", text="Search")
691
692         col.prop(sc, "show_tiny_markers", text="Thin Markers")
693         col.prop(sc, "show_track_path", text="Path")
694
695         row = col.row()
696         row.active = sc.show_track_path
697         row.prop(sc, "path_length", text="Length")
698
699
700 class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel):
701     bl_space_type = 'CLIP_EDITOR'
702     bl_region_type = 'UI'
703     bl_label = "2D Stabilization"
704     bl_options = {'DEFAULT_CLOSED'}
705
706     def draw_header(self, context):
707         stab = context.space_data.clip.tracking.stabilization
708
709         self.layout.prop(stab, "use_2d_stabilization", text="")
710
711     def draw(self, context):
712         layout = self.layout
713
714         tracking = context.space_data.clip.tracking
715         stab = tracking.stabilization
716
717         layout.active = stab.use_2d_stabilization
718
719         row = layout.row()
720         row.template_list(stab, "tracks", stab, "active_track_index", rows=3)
721
722         sub = row.column(align=True)
723
724         sub.operator("clip.stabilize_2d_add", icon='ZOOMIN', text="")
725         sub.operator("clip.stabilize_2d_remove", icon='ZOOMOUT', text="")
726
727         sub.menu('CLIP_MT_stabilize_2d_specials', text="",
728                  icon='DOWNARROW_HLT')
729
730         layout.prop(stab, "influence_location")
731
732         layout.prop(stab, "use_autoscale")
733         col = layout.column()
734         col.active = stab.use_autoscale
735         col.prop(stab, "scale_max")
736         col.prop(stab, "influence_scale")
737
738         layout.prop(stab, "use_stabilize_rotation")
739         col = layout.column()
740         col.active = stab.use_stabilize_rotation
741
742         row = col.row(align=True)
743         row.prop_search(stab, "rotation_track", tracking, "tracks", text="")
744         row.operator("clip.stabilize_2d_set_rotation", text="", icon='ZOOMIN')
745
746         row = col.row()
747         row.active = stab.rotation_track is not None
748         row.prop(stab, "influence_rotation")
749
750         layout.prop(stab, "filter_type")
751
752
753 class CLIP_PT_marker(CLIP_PT_tracking_panel, Panel):
754     bl_space_type = 'CLIP_EDITOR'
755     bl_region_type = 'UI'
756     bl_label = "Marker"
757     bl_options = {'DEFAULT_CLOSED'}
758
759     def draw(self, context):
760         layout = self.layout
761         sc = context.space_data
762         clip = context.space_data.clip
763         act_track = clip.tracking.tracks.active
764
765         if act_track:
766             layout.template_marker(sc, "clip", sc.clip_user, act_track, False)
767         else:
768             layout.active = False
769             layout.label(text="No active track")
770
771
772 class CLIP_PT_proxy(CLIP_PT_clip_view_panel, Panel):
773     bl_space_type = 'CLIP_EDITOR'
774     bl_region_type = 'UI'
775     bl_label = "Proxy / Timecode"
776     bl_options = {'DEFAULT_CLOSED'}
777
778     def draw_header(self, context):
779         sc = context.space_data
780
781         self.layout.prop(sc.clip, "use_proxy", text="")
782
783     def draw(self, context):
784         layout = self.layout
785         sc = context.space_data
786         clip = sc.clip
787
788         layout.active = clip.use_proxy
789
790         layout.label(text="Build Original:")
791
792         row = layout.row(align=True)
793         row.prop(clip.proxy, "build_25", toggle=True)
794         row.prop(clip.proxy, "build_50", toggle=True)
795         row.prop(clip.proxy, "build_75", toggle=True)
796         row.prop(clip.proxy, "build_100", toggle=True)
797
798         layout.label(text="Build Undistorted:")
799
800         row = layout.row(align=True)
801         row.prop(clip.proxy, "build_undistorted_25", toggle=True)
802         row.prop(clip.proxy, "build_undistorted_50", toggle=True)
803         row.prop(clip.proxy, "build_undistorted_75", toggle=True)
804         row.prop(clip.proxy, "build_undistorted_100", toggle=True)
805
806         layout.prop(clip.proxy, "quality")
807
808         layout.prop(clip, "use_proxy_custom_directory")
809         if clip.use_proxy_custom_directory:
810             layout.prop(clip.proxy, "directory")
811
812         layout.operator("clip.rebuild_proxy", text="Build Proxy")
813
814         if clip.source == 'MOVIE':
815             col = layout.column()
816
817             col.label(text="Use timecode index:")
818             col.prop(clip.proxy, "timecode", text="")
819
820         col = layout.column()
821         col.label(text="Proxy render size:")
822
823         col.prop(sc.clip_user, "proxy_render_size", text="")
824         col.prop(sc.clip_user, "use_render_undistorted")
825
826
827 class CLIP_PT_footage(CLIP_PT_clip_view_panel, Panel):
828     bl_space_type = 'CLIP_EDITOR'
829     bl_region_type = 'UI'
830     bl_label = "Footage Settings"
831     bl_options = {'DEFAULT_CLOSED'}
832
833     def draw(self, context):
834         layout = self.layout
835
836         sc = context.space_data
837         clip = sc.clip
838
839         col = layout.column()
840         col.template_movieclip(sc, "clip", compact=True)
841         col.prop(clip, "start_frame")
842         col.prop(clip, "frame_offset")
843
844
845 class CLIP_PT_tools_clip(CLIP_PT_clip_view_panel, Panel):
846     bl_space_type = 'CLIP_EDITOR'
847     bl_region_type = 'TOOLS'
848     bl_label = "Clip"
849
850     def draw(self, context):
851         layout = self.layout
852
853         layout.operator("clip.set_viewport_background")
854         layout.operator("clip.setup_tracking_scene")
855
856
857 class CLIP_MT_view(Menu):
858     bl_label = "View"
859
860     def draw(self, context):
861         layout = self.layout
862         sc = context.space_data
863
864         if sc.view == 'CLIP':
865             layout.operator("clip.properties", icon='MENU_PANEL')
866             layout.operator("clip.tools", icon='MENU_PANEL')
867             layout.separator()
868
869             layout.operator("clip.view_selected")
870             layout.operator("clip.view_all")
871
872             layout.separator()
873             layout.operator("clip.view_zoom_in")
874             layout.operator("clip.view_zoom_out")
875
876             layout.separator()
877
878             ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
879
880             for a, b in ratios:
881                 text = "Zoom %d:%d" % (a, b)
882                 layout.operator("clip.view_zoom_ratio",
883                                 text=text).ratio = a / b
884         else:
885             layout.prop(sc, "show_seconds")
886             layout.separator()
887
888         layout.separator()
889         layout.operator("screen.area_dupli")
890         layout.operator("screen.screen_full_area")
891
892
893 class CLIP_MT_clip(Menu):
894     bl_label = "Clip"
895
896     def draw(self, context):
897         layout = self.layout
898
899         sc = context.space_data
900         clip = sc.clip
901
902         layout.operator("clip.open")
903
904         if clip:
905             layout.operator("clip.reload")
906             layout.menu("CLIP_MT_proxy")
907
908
909 class CLIP_MT_proxy(Menu):
910     bl_label = "Proxy"
911
912     def draw(self, context):
913         layout = self.layout
914
915         layout.operator("clip.rebuild_proxy")
916         layout.operator("clip.delete_proxy")
917
918
919 class CLIP_MT_track(Menu):
920     bl_label = "Track"
921
922     def draw(self, context):
923         layout = self.layout
924
925         layout.operator("clip.clear_solution")
926         layout.operator("clip.solve_camera")
927
928         layout.separator()
929         props = layout.operator("clip.clear_track_path", text="Clear After")
930         props.action = 'REMAINED'
931
932         props = layout.operator("clip.clear_track_path", text="Clear Before")
933         props.action = 'UPTO'
934
935         props = layout.operator("clip.clear_track_path",
936             text="Clear Track Path")
937         props.action = 'ALL'
938
939         layout.separator()
940         layout.operator("clip.join_tracks")
941
942         layout.separator()
943         layout.operator("clip.clean_tracks")
944
945         layout.separator()
946         layout.operator("clip.copy_tracks")
947         layout.operator("clip.paste_tracks")
948
949         layout.separator()
950         props = layout.operator("clip.track_markers",
951             text="Track Frame Backwards")
952         props.backwards = True
953
954         props = layout.operator("clip.track_markers", text="Track Backwards")
955         props.backwards = True
956         props.sequence = True
957
958         props = layout.operator("clip.track_markers", text="Track Forwards")
959         props.sequence = True
960         layout.operator("clip.track_markers", text="Track Frame Forwards")
961
962         layout.separator()
963         layout.operator("clip.delete_track")
964         layout.operator("clip.delete_marker")
965
966         layout.separator()
967         layout.operator("clip.add_marker_move")
968
969         layout.separator()
970         layout.menu("CLIP_MT_track_visibility")
971         layout.menu("CLIP_MT_track_transform")
972
973
974 class CLIP_MT_reconstruction(Menu):
975     bl_label = "Reconstruction"
976
977     def draw(self, context):
978         layout = self.layout
979
980         layout.operator("clip.set_origin")
981         props = layout.operator("clip.set_plane", text="Set Floor")
982         props.plane = 'FLOOR'
983         props = layout.operator("clip.set_plane", text="Set Wall")
984         props.plane = 'WALL'
985
986         layout.operator("clip.set_axis", text="Set X Axis").axis = "X"
987         layout.operator("clip.set_axis", text="Set Y Axis").axis = "Y"
988
989         layout.operator("clip.set_scale")
990
991         layout.separator()
992
993         layout.operator("clip.track_to_empty")
994         layout.operator("clip.bundles_to_mesh")
995
996
997 class CLIP_MT_track_visibility(Menu):
998     bl_label = "Show/Hide"
999
1000     def draw(self, context):
1001         layout = self.layout
1002
1003         layout.operator("clip.hide_tracks_clear", text="Show Hidden")
1004         layout.operator("clip.hide_tracks", text="Hide Selected")
1005
1006         props = layout.operator("clip.hide_tracks", text="Hide Unselected")
1007         props.unselected = True
1008
1009
1010 class CLIP_MT_track_transform(Menu):
1011     bl_label = "Transform"
1012
1013     def draw(self, context):
1014         layout = self.layout
1015
1016         layout.operator("transform.translate")
1017         layout.operator("transform.resize")
1018
1019
1020 class CLIP_MT_select(Menu):
1021     bl_label = "Select"
1022
1023     def draw(self, context):
1024         layout = self.layout
1025
1026         layout.operator("clip.select_border")
1027         layout.operator("clip.select_circle")
1028
1029         layout.separator()
1030
1031         layout.operator("clip.select_all"
1032                         ).action = 'TOGGLE'
1033         layout.operator("clip.select_all",
1034                         text="Inverse").action = 'INVERT'
1035
1036         layout.menu("CLIP_MT_select_grouped")
1037
1038
1039 class CLIP_MT_select_grouped(Menu):
1040     bl_label = "Select Grouped"
1041
1042     def draw(self, context):
1043         layout = self.layout
1044
1045         layout.operator_enum("clip.select_grouped", "group")
1046
1047
1048 class CLIP_MT_tracking_specials(Menu):
1049     bl_label = "Specials"
1050
1051     @classmethod
1052     def poll(cls, context):
1053         return context.space_data.clip
1054
1055     def draw(self, context):
1056         layout = self.layout
1057
1058         props = layout.operator("clip.disable_markers",
1059                                 text="Enable Markers")
1060         props.action = 'ENABLE'
1061
1062         props = layout.operator("clip.disable_markers", text="Disable markers")
1063         props.action = 'DISABLE'
1064
1065         layout.separator()
1066         layout.operator("clip.set_origin")
1067
1068         layout.separator()
1069         layout.operator("clip.hide_tracks")
1070         layout.operator("clip.hide_tracks_clear", text="Show Tracks")
1071
1072         layout.separator()
1073         props = layout.operator("clip.lock_tracks", text="Lock Tracks")
1074         props.action = 'LOCK'
1075
1076         props = layout.operator("clip.lock_tracks", text="Unlock Tracks")
1077         props.action = 'UNLOCK'
1078
1079
1080 class CLIP_MT_select_mode(Menu):
1081     bl_label = "Select Mode"
1082
1083     def draw(self, context):
1084         layout = self.layout
1085
1086         layout.operator_context = 'INVOKE_REGION_WIN'
1087
1088         layout.operator_enum("clip.mode_set", "mode")
1089
1090
1091 class CLIP_MT_camera_presets(Menu):
1092     """Predefined tracking camera intrinsics"""
1093     bl_label = "Camera Presets"
1094     preset_subdir = "tracking_camera"
1095     preset_operator = "script.execute_preset"
1096     draw = Menu.draw_preset
1097
1098
1099 class CLIP_MT_track_color_presets(Menu):
1100     """Predefined track color"""
1101     bl_label = "Color Presets"
1102     preset_subdir = "tracking_track_color"
1103     preset_operator = "script.execute_preset"
1104     draw = Menu.draw_preset
1105
1106
1107 class CLIP_MT_tracking_settings_presets(Menu):
1108     """Predefined tracking settings"""
1109     bl_label = "Tracking Presets"
1110     preset_subdir = "tracking_settings"
1111     preset_operator = "script.execute_preset"
1112     draw = Menu.draw_preset
1113
1114
1115 class CLIP_MT_track_color_specials(Menu):
1116     bl_label = "Track Color Specials"
1117
1118     def draw(self, context):
1119         layout = self.layout
1120
1121         layout.operator("clip.track_copy_color", icon='COPY_ID')
1122
1123
1124 class CLIP_MT_stabilize_2d_specials(Menu):
1125     bl_label = "Track Color Specials"
1126
1127     def draw(self, context):
1128         layout = self.layout
1129
1130         layout.operator("clip.stabilize_2d_select")
1131
1132
1133 # -----------------------------------------------------------------------------
1134 # Mask (similar code in space_image.py, keep in sync)
1135
1136
1137 from bl_ui.properties_mask_common import (MASK_PT_mask,
1138                                           MASK_PT_layers,
1139                                           MASK_PT_spline,
1140                                           MASK_PT_point,
1141                                           MASK_PT_display,
1142                                           MASK_PT_tools)
1143
1144
1145 class CLIP_PT_mask(MASK_PT_mask, Panel):
1146     bl_space_type = 'CLIP_EDITOR'
1147     bl_region_type = 'UI'
1148
1149
1150 class CLIP_PT_mask_layers(MASK_PT_layers, Panel):
1151     bl_space_type = 'CLIP_EDITOR'
1152     bl_region_type = 'UI'
1153
1154
1155 class CLIP_PT_mask_display(MASK_PT_display, Panel):
1156     bl_space_type = 'CLIP_EDITOR'
1157     bl_region_type = 'UI'
1158
1159
1160 class CLIP_PT_active_mask_spline(MASK_PT_spline, Panel):
1161     bl_space_type = 'CLIP_EDITOR'
1162     bl_region_type = 'UI'
1163
1164
1165 class CLIP_PT_active_mask_point(MASK_PT_point, Panel):
1166     bl_space_type = 'CLIP_EDITOR'
1167     bl_region_type = 'UI'
1168
1169 class CLIP_PT_tools_mask(MASK_PT_tools, Panel):
1170     bl_space_type = 'CLIP_EDITOR'
1171     bl_region_type = 'TOOLS'
1172
1173 # --- end mask ---
1174
1175 if __name__ == "__main__":  # only for live edit.
1176     bpy.utils.register_module(__name__)