more minor py edits
[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 compliant>
20 import bpy
21 from bpy.types import Panel, Header, Menu
22
23
24 class CLIP_HT_header(Header):
25     bl_space_type = 'CLIP_EDITOR'
26
27     def draw(self, context):
28         layout = self.layout
29
30         sc = context.space_data
31         clip = sc.clip
32
33         row = layout.row(align=True)
34         row.template_header()
35
36         if context.area.show_menus:
37             sub = row.row(align=True)
38             sub.menu("CLIP_MT_view")
39
40             if clip:
41                 sub.menu("CLIP_MT_select")
42
43             sub.menu("CLIP_MT_clip")
44
45             if clip:
46                 sub.menu("CLIP_MT_track")
47                 sub.menu("CLIP_MT_reconstruction")
48
49         if clip:
50             layout.prop(sc, "mode", text="")
51             layout.prop(sc, "view", text="", expand=True)
52
53             if sc.view == 'GRAPH':
54                 row = layout.row(align=True)
55
56                 if sc.show_filters:
57                     row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_DOWN',
58                         text="Filters")
59
60                     sub = row.column()
61                     sub.active = clip.tracking.reconstruction.is_valid
62                     sub.prop(sc, "show_graph_frames", icon='SEQUENCE', text="")
63
64                     row.prop(sc, "show_graph_tracks", icon='ANIM', text="")
65                 else:
66                     row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_RIGHT',
67                         text="Filters")
68
69         row = layout.row()
70         row.template_ID(sc, "clip", open='clip.open')
71
72         if clip:
73             r = clip.tracking.reconstruction
74
75             if r.is_valid:
76                 layout.label(text="Average solve error: %.4f" %
77                     (r.average_error))
78
79         layout.template_running_jobs()
80
81
82 class CLIP_PT_tools_marker(Panel):
83     bl_space_type = 'CLIP_EDITOR'
84     bl_region_type = 'TOOLS'
85     bl_label = "Marker"
86
87     @classmethod
88     def poll(cls, context):
89         sc = context.space_data
90         clip = sc.clip
91
92         return clip and sc.mode == 'TRACKING'
93
94     def draw(self, context):
95         sc = context.space_data
96         clip = sc.clip
97         settings = clip.tracking.settings
98         layout = self.layout
99
100         col = layout.column(align=True)
101         col.operator("clip.add_marker_move")
102         col.operator("clip.detect_features")
103         col.operator("clip.delete_track")
104
105         box = layout.box()
106         row = box.row(align=True)
107         row.prop(settings, "show_default_expanded", text="", emboss=False)
108         row.label(text="Tracking Settings")
109
110         if settings.show_default_expanded:
111             col = box.column()
112             row = col.row(align=True)
113             label = bpy.types.CLIP_MT_tracking_settings_presets.bl_label
114             row.menu('CLIP_MT_tracking_settings_presets', text=label)
115             row.operator("clip.tracking_settings_preset_add",
116                          text="", icon='ZOOMIN')
117             props = row.operator("clip.track_color_preset_add",
118                                  text="", icon='ZOOMOUT')
119             props.remove_active = True
120
121             col.separator()
122
123             sub = col.column(align=True)
124             sub.prop(settings, "default_pattern_size")
125             sub.prop(settings, "default_search_size")
126
127             col.label(text="Tracker:")
128             col.prop(settings, "default_tracker", text="")
129
130             if settings.default_tracker == 'KLT':
131                 col.prop(settings, "default_pyramid_levels")
132             elif settings.default_tracker == 'SAD':
133                 col.prop(settings, "default_correlation_min")
134
135             col.separator()
136
137             sub = col.column(align=True)
138             sub.prop(settings, "default_frames_limit")
139             sub.prop(settings, "default_margin")
140
141             col.label(text="Match:")
142             col.prop(settings, "default_pattern_match", text="")
143
144
145 class CLIP_PT_tools_tracking(Panel):
146     bl_space_type = 'CLIP_EDITOR'
147     bl_region_type = 'TOOLS'
148     bl_label = "Track"
149
150     @classmethod
151     def poll(cls, context):
152         sc = context.space_data
153         clip = sc.clip
154
155         return clip and sc.mode == 'TRACKING'
156
157     def draw(self, context):
158         layout = self.layout
159         # clip = context.space_data.clip  # UNUSED
160
161         row = layout.row(align=True)
162
163         props = row.operator("clip.track_markers", text="", icon='FRAME_PREV')
164         props.backwards = True
165         props = row.operator("clip.track_markers", text="",
166              icon='PLAY_REVERSE')
167         props.backwards = True
168         props.sequence = True
169         props = row.operator("clip.track_markers", text="", icon='PLAY')
170         props.sequence = True
171         row.operator("clip.track_markers", text="", icon='FRAME_NEXT')
172
173         col = layout.column(align=True)
174         props = col.operator("clip.clear_track_path", text="Clear After")
175         props.action = 'REMAINED'
176
177         props = col.operator("clip.clear_track_path", text="Clear Before")
178         props.action = 'UPTO'
179
180         props = col.operator("clip.clear_track_path", text="Clear")
181         props.action = 'ALL'
182
183         layout.operator("clip.join_tracks", text="Join")
184
185
186 class CLIP_PT_tools_solve(Panel):
187     bl_space_type = 'CLIP_EDITOR'
188     bl_region_type = 'TOOLS'
189     bl_label = "Solve"
190
191     @classmethod
192     def poll(cls, context):
193         sc = context.space_data
194         clip = sc.clip
195
196         return clip and sc.mode == 'TRACKING'
197
198     def draw(self, context):
199         layout = self.layout
200         clip = context.space_data.clip
201         settings = clip.tracking.settings
202
203         col = layout.column(align=True)
204         col.operator("clip.solve_camera", text="Camera Motion")
205         col.operator("clip.clear_solution")
206
207         col = layout.column(align=True)
208         col.prop(settings, "keyframe_a")
209         col.prop(settings, "keyframe_b")
210
211         col = layout.column(align=True)
212         col.label(text="Refine:")
213         col.prop(settings, "refine_intrinsics", text="")
214
215
216 class CLIP_PT_tools_cleanup(Panel):
217     bl_space_type = 'CLIP_EDITOR'
218     bl_region_type = 'TOOLS'
219     bl_label = "Clean up"
220
221     @classmethod
222     def poll(cls, context):
223         sc = context.space_data
224         clip = sc.clip
225
226         return clip and sc.mode == 'TRACKING'
227
228     def draw(self, context):
229         layout = self.layout
230         clip = context.space_data.clip
231         settings = clip.tracking.settings
232
233         layout.operator("clip.clean_tracks")
234
235         layout.prop(settings, 'clean_frames', text="Frames")
236         layout.prop(settings, 'clean_error', text="Error")
237         layout.prop(settings, 'clean_action', text="")
238
239
240 class CLIP_PT_tools_geometry(Panel):
241     bl_space_type = 'CLIP_EDITOR'
242     bl_region_type = 'TOOLS'
243     bl_label = "Geometry"
244
245     @classmethod
246     def poll(cls, context):
247         sc = context.space_data
248         clip = sc.clip
249
250         return clip and sc.mode == 'RECONSTRUCTION'
251
252     def draw(self, context):
253         layout = self.layout
254
255         layout.operator("clip.bundles_to_mesh")
256         layout.operator("clip.track_to_empty")
257
258
259 class CLIP_PT_tools_orientation(Panel):
260     bl_space_type = 'CLIP_EDITOR'
261     bl_region_type = 'TOOLS'
262     bl_label = "Orientation"
263
264     @classmethod
265     def poll(cls, context):
266         sc = context.space_data
267         clip = sc.clip
268
269         return clip and sc.mode == 'RECONSTRUCTION'
270
271     def draw(self, context):
272         sc = context.space_data
273         layout = self.layout
274         settings = sc.clip.tracking.settings
275
276         col = layout.column(align=True)
277         col.operator("clip.set_floor")
278         col.operator("clip.set_origin")
279
280         row = col.row()
281         row.operator("clip.set_axis", text="Set X Axis").axis = 'X'
282         row.operator("clip.set_axis", text="Set Y Axis").axis = 'Y'
283
284         layout.separator()
285
286         col = layout.column()
287         col.operator("clip.set_scale")
288         col.prop(settings, "distance")
289
290
291 class CLIP_PT_tools_grease_pencil(Panel):
292     bl_space_type = 'CLIP_EDITOR'
293     bl_region_type = 'TOOLS'
294     bl_label = "Grease Pencil"
295
296     @classmethod
297     def poll(cls, context):
298         sc = context.space_data
299         clip = sc.clip
300
301         return clip and sc.mode == 'DISTORTION'
302
303     def draw(self, context):
304         layout = self.layout
305
306         col = layout.column(align=True)
307
308         row = col.row(align=True)
309         row.operator("gpencil.draw", text="Draw").mode = 'DRAW'
310         row.operator("gpencil.draw", text="Line").mode = 'DRAW_STRAIGHT'
311
312         row = col.row(align=True)
313         row.operator("gpencil.draw", text="Poly").mode = 'DRAW_POLY'
314         row.operator("gpencil.draw", text="Erase").mode = 'ERASER'
315
316         row = col.row()
317         row.prop(context.tool_settings, "use_grease_pencil_sessions")
318
319
320 class CLIP_PT_track(Panel):
321     bl_space_type = 'CLIP_EDITOR'
322     bl_region_type = 'UI'
323     bl_label = "Track"
324
325     @classmethod
326     def poll(cls, context):
327         sc = context.space_data
328         clip = sc.clip
329
330         return sc.mode == 'TRACKING' and clip
331
332     def draw(self, context):
333         layout = self.layout
334         sc = context.space_data
335         clip = context.space_data.clip
336         act_track = clip.tracking.tracks.active
337
338         if not act_track:
339             layout.active = False
340             layout.label(text="No active track")
341             return
342
343         row = layout.row()
344         row.prop(act_track, "name", text="")
345
346         sub = row.row(align=True)
347
348         sub.template_marker(sc, "clip", sc.clip_user, act_track, True)
349
350         icon = 'LOCKED' if act_track.lock else 'UNLOCKED'
351         sub.prop(act_track, "lock", text="", icon=icon)
352
353         layout.template_track(sc, "scopes")
354
355         row = layout.row(align=True)
356         row.prop(act_track, "use_red_channel", text="R", toggle=True)
357         row.prop(act_track, "use_green_channel", text="G", toggle=True)
358         row.prop(act_track, "use_blue_channel", text="B", toggle=True)
359
360         layout.separator()
361
362         row = layout.row(align=True)
363         label = bpy.types.CLIP_MT_track_color_presets.bl_label
364         row.menu('CLIP_MT_track_color_presets', text=label)
365         row.menu('CLIP_MT_track_color_specials', text="", icon='DOWNARROW_HLT')
366         row.operator("clip.track_color_preset_add", text="", icon='ZOOMIN')
367         props = row.operator("clip.track_color_preset_add",
368                              text="", icon='ZOOMOUT')
369         props.remove_active = True
370
371         row = layout.row()
372         row.prop(act_track, "use_custom_color")
373         if act_track.use_custom_color:
374             row.prop(act_track, "color", text="")
375
376         if act_track.has_bundle:
377             label_text = "Average Error: %.4f" % (act_track.average_error)
378             layout.label(text=label_text)
379
380
381 class CLIP_PT_tracking_camera(Panel):
382     bl_space_type = 'CLIP_EDITOR'
383     bl_region_type = 'UI'
384     bl_label = "Camera Data"
385     bl_options = {'DEFAULT_CLOSED'}
386
387     @classmethod
388     def poll(cls, context):
389         sc = context.space_data
390
391         return sc.mode in ['TRACKING', 'DISTORTION'] and sc.clip
392
393     def draw(self, context):
394         layout = self.layout
395
396         sc = context.space_data
397         clip = sc.clip
398
399         row = layout.row(align=True)
400         label = bpy.types.CLIP_MT_camera_presets.bl_label
401         row.menu('CLIP_MT_camera_presets', text=label)
402         row.operator("clip.camera_preset_add", text="", icon='ZOOMIN')
403         props = row.operator("clip.camera_preset_add", text="", icon='ZOOMOUT')
404         props.remove_active = True
405
406         row = layout.row(align=True)
407         sub = row.split(percentage=0.65)
408         if clip.tracking.camera.units == 'MILLIMETERS':
409             sub.prop(clip.tracking.camera, "focal_length")
410         else:
411             sub.prop(clip.tracking.camera, "focal_length_pixels")
412         sub.prop(clip.tracking.camera, "units", text="")
413
414         col = layout.column(align=True)
415         col.label(text="Sensor:")
416         col.prop(clip.tracking.camera, "sensor_width", text="Width")
417         col.prop(clip.tracking.camera, "pixel_aspect")
418
419         col = layout.column()
420         col.label(text="Optical Center:")
421         row = col.row()
422         row.prop(clip.tracking.camera, "principal", text="")
423         col.operator("clip.set_center_principal", text="Center")
424
425         col = layout.column(align=True)
426         col.label(text="Undistortion:")
427         col.prop(clip.tracking.camera, "k1")
428         col.prop(clip.tracking.camera, "k2")
429         col.prop(clip.tracking.camera, "k3")
430
431
432 class CLIP_PT_display(Panel):
433     bl_space_type = 'CLIP_EDITOR'
434     bl_region_type = 'UI'
435     bl_label = "Display"
436
437     def draw(self, context):
438         layout = self.layout
439         sc = context.space_data
440
441         col = layout.column(align=True)
442
443         col.prop(sc, "show_marker_pattern", text="Pattern")
444         col.prop(sc, "show_marker_search", text="Search")
445         col.prop(sc, "show_pyramid_levels", text="Pyramid")
446
447         col.prop(sc, "show_track_path", text="Path")
448         row = col.row()
449         row.active = sc.show_track_path
450         row.prop(sc, "path_length", text="Length")
451
452         col.prop(sc, "show_disabled", "Disabled Tracks")
453         col.prop(sc, "show_bundles", text="3D Markers")
454
455         col.prop(sc, "show_names", text="Names and Status")
456         col.prop(sc, "show_tiny_markers", text="Compact Markers")
457
458         col.prop(sc, "show_grease_pencil", text="Grease Pencil")
459         col.prop(sc, "use_mute_footage", text="Mute")
460
461         if sc.mode == 'DISTORTION':
462             col.prop(sc, "show_grid", text="Grid")
463             col.prop(sc, "use_manual_calibration")
464         elif sc.mode == 'RECONSTRUCTION':
465             col.prop(sc, "show_stable", text="Stable")
466
467         col.prop(sc, "lock_selection")
468
469         clip = sc.clip
470         if clip:
471             col.label(text="Display Aspect Ratio:")
472             col.prop(clip, "display_aspect", text="")
473
474
475 class CLIP_PT_track_settings(Panel):
476     bl_space_type = 'CLIP_EDITOR'
477     bl_region_type = 'UI'
478     bl_label = "Tracking Settings"
479     bl_options = {'DEFAULT_CLOSED'}
480
481     @classmethod
482     def poll(cls, context):
483         sc = context.space_data
484
485         return sc.mode == 'TRACKING' and sc.clip
486
487     def draw(self, context):
488         layout = self.layout
489         clip = context.space_data.clip
490         settings = clip.tracking.settings
491
492         col = layout.column()
493
494         active = clip.tracking.tracks.active
495         if active:
496             col.prop(active, "tracker")
497
498             if active.tracker == 'KLT':
499                 col.prop(active, "pyramid_levels")
500             elif active.tracker == 'SAD':
501                 col.prop(active, "correlation_min")
502
503             col.separator()
504             col.prop(active, "frames_limit")
505             col.prop(active, "margin")
506             col.prop(active, "pattern_match", text="Match")
507
508         col.prop(settings, "speed")
509
510
511 class CLIP_PT_stabilization(Panel):
512     bl_space_type = 'CLIP_EDITOR'
513     bl_region_type = 'UI'
514     bl_label = "2D Stabilization"
515     bl_options = {'DEFAULT_CLOSED'}
516
517     @classmethod
518     def poll(cls, context):
519         sc = context.space_data
520
521         return sc.mode == 'RECONSTRUCTION' and sc.clip
522
523     def draw_header(self, context):
524         stab = context.space_data.clip.tracking.stabilization
525
526         self.layout.prop(stab, "use_2d_stabilization", text="")
527
528     def draw(self, context):
529         layout = self.layout
530
531         tracking = context.space_data.clip.tracking
532         stab = tracking.stabilization
533
534         layout.active = stab.use_2d_stabilization
535
536         row = layout.row()
537         row.template_list(stab, "tracks", stab, "active_track_index", rows=3)
538
539         sub = row.column(align=True)
540
541         sub.operator("clip.stabilize_2d_add", icon='ZOOMIN', text="")
542         sub.operator("clip.stabilize_2d_remove", icon='ZOOMOUT', text="")
543
544         sub.menu('CLIP_MT_stabilize_2d_specials', text="",
545                  icon='DOWNARROW_HLT')
546
547         layout.prop(stab, "influence_location")
548
549         layout.prop(stab, "use_autoscale")
550         col = layout.column()
551         col.active = stab.use_autoscale
552         col.prop(stab, "scale_max")
553         col.prop(stab, "influence_scale")
554
555         layout.prop(stab, "use_stabilize_rotation")
556         col = layout.column()
557         col.active = stab.use_stabilize_rotation
558
559         row = col.row(align=True)
560         row.prop_search(stab, "rotation_track", tracking, "tracks", text="")
561         row.operator("clip.stabilize_2d_set_rotation", text="", icon='ZOOMIN')
562
563         row = col.row()
564         row.active = stab.rotation_track is not None
565         row.prop(stab, "influence_rotation")
566
567
568 class CLIP_PT_marker(Panel):
569     bl_space_type = 'CLIP_EDITOR'
570     bl_region_type = 'UI'
571     bl_label = "Marker"
572     bl_options = {'DEFAULT_CLOSED'}
573
574     @classmethod
575     def poll(cls, context):
576         sc = context.space_data
577         clip = sc.clip
578
579         return sc.mode == 'TRACKING' and clip
580
581     def draw(self, context):
582         layout = self.layout
583         sc = context.space_data
584         clip = context.space_data.clip
585         act_track = clip.tracking.tracks.active
586
587         if act_track:
588             layout.template_marker(sc, "clip", sc.clip_user, act_track, False)
589         else:
590             layout.active = False
591             layout.label(text="No active track")
592
593
594 class CLIP_PT_proxy(Panel):
595     bl_space_type = 'CLIP_EDITOR'
596     bl_region_type = 'UI'
597     bl_label = "Proxy / Timecode"
598     bl_options = {'DEFAULT_CLOSED'}
599
600     @classmethod
601     def poll(cls, context):
602         sc = context.space_data
603
604         return sc.clip
605
606     def draw_header(self, context):
607         sc = context.space_data
608
609         self.layout.prop(sc.clip, "use_proxy", text="")
610
611     def draw(self, context):
612         layout = self.layout
613         sc = context.space_data
614         clip = sc.clip
615
616         layout.active = clip.use_proxy
617
618         layout.label(text="Build Sizes:")
619
620         row = layout.row()
621         row.prop(clip.proxy, "build_25")
622         row.prop(clip.proxy, "build_50")
623
624         row = layout.row()
625         row.prop(clip.proxy, "build_75")
626         row.prop(clip.proxy, "build_100")
627
628         layout.prop(clip.proxy, "build_undistorted")
629
630         layout.prop(clip.proxy, "quality")
631
632         layout.prop(clip, 'use_proxy_custom_directory')
633         if clip.use_proxy_custom_directory:
634             layout.prop(clip.proxy, "directory")
635
636         layout.operator("clip.rebuild_proxy", text="Rebuild Proxy")
637
638         if clip.source == 'MOVIE':
639             col = layout.column()
640
641             col.label(text="Use timecode index:")
642             col.prop(clip.proxy, "timecode", text="")
643
644         col = layout.column()
645         col.label(text="Proxy render size:")
646
647         col.prop(sc.clip_user, "proxy_render_size", text="")
648         col.prop(sc.clip_user, "use_render_undistorted")
649
650
651 class CLIP_PT_footage(Panel):
652     bl_space_type = 'CLIP_EDITOR'
653     bl_region_type = 'UI'
654     bl_label = "Footage Settings"
655     bl_options = {'DEFAULT_CLOSED'}
656
657     @classmethod
658     def poll(cls, context):
659         sc = context.space_data
660
661         return sc.clip
662
663     def draw(self, context):
664         layout = self.layout
665
666         sc = context.space_data
667         clip = sc.clip
668
669         if clip:
670             layout.template_movieclip(sc, "clip", compact=True)
671         else:
672             layout.operator("clip.open", icon='FILESEL')
673
674
675 class CLIP_PT_tools_clip(Panel):
676     bl_space_type = 'CLIP_EDITOR'
677     bl_region_type = 'TOOLS'
678     bl_label = "Clip"
679
680     @classmethod
681     def poll(cls, context):
682         sc = context.space_data
683
684         return sc.clip
685
686     def draw(self, context):
687         layout = self.layout
688
689         layout.operator("clip.set_viewport_background")
690         layout.operator("clip.setup_tracking_scene")
691
692
693 class CLIP_MT_view(Menu):
694     bl_label = "View"
695
696     def draw(self, context):
697         layout = self.layout
698
699         layout.operator("clip.properties", icon='MENU_PANEL')
700         layout.operator("clip.tools", icon='MENU_PANEL')
701         layout.separator()
702
703         layout.operator("clip.view_selected")
704         layout.operator("clip.view_all")
705
706         layout.separator()
707         layout.operator("clip.view_zoom_in")
708         layout.operator("clip.view_zoom_out")
709
710         layout.separator()
711
712         ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
713
714         for a, b in ratios:
715             text = "Zoom %d:%d" % (a, b)
716             layout.operator("clip.view_zoom_ratio", text=text).ratio = a / b
717
718         layout.separator()
719         layout.operator("screen.area_dupli")
720         layout.operator("screen.screen_full_area")
721
722
723 class CLIP_MT_clip(Menu):
724     bl_label = "Clip"
725
726     def draw(self, context):
727         layout = self.layout
728
729         sc = context.space_data
730         clip = sc.clip
731
732         layout.operator("clip.open")
733
734         if clip:
735             layout.operator("clip.reload")
736             layout.menu("CLIP_MT_proxy")
737
738
739 class CLIP_MT_proxy(Menu):
740     bl_label = "Proxy"
741
742     def draw(self, context):
743         layout = self.layout
744
745         layout.operator("clip.rebuild_proxy")
746         layout.operator("clip.delete_proxy")
747
748
749 class CLIP_MT_track(Menu):
750     bl_label = "Track"
751
752     def draw(self, context):
753         layout = self.layout
754
755         layout.operator("clip.clear_solution")
756         layout.operator("clip.solve_camera")
757
758         layout.separator()
759         props = layout.operator("clip.clear_track_path", text="Clear After")
760         props.action = 'REMAINED'
761
762         props = layout.operator("clip.clear_track_path", text="Clear Before")
763         props.action = 'UPTO'
764
765         props = layout.operator("clip.clear_track_path",
766             text="Clear Track Path")
767         props.action = 'ALL'
768
769         layout.separator()
770         layout.operator("clip.join_tracks")
771
772         layout.separator()
773         layout.operator("clip.clean_tracks")
774
775         layout.separator()
776         props = layout.operator("clip.track_markers",
777             text="Track Frame Backwards")
778         props.backwards = True
779
780         props = layout.operator("clip.track_markers", text="Track Backwards")
781         props.backwards = True
782         props.sequence = True
783
784         props = layout.operator("clip.track_markers", text="Track Forwards")
785         props.sequence = True
786         layout.operator("clip.track_markers", text="Track Frame Forwards")
787
788         layout.separator()
789         layout.operator("clip.delete_track")
790         layout.operator("clip.delete_marker")
791
792         layout.separator()
793         layout.operator("clip.add_marker_move")
794
795         layout.separator()
796         layout.menu("CLIP_MT_track_visibility")
797         layout.menu("CLIP_MT_track_transform")
798
799
800 class CLIP_MT_reconstruction(Menu):
801     bl_label = "Reconstruction"
802
803     def draw(self, context):
804         layout = self.layout
805
806         layout.operator("clip.set_origin")
807         layout.operator("clip.set_floor")
808
809         layout.operator("clip.set_axis", text="Set X Axis").axis = "X"
810         layout.operator("clip.set_axis", text="Set Y Axis").axis = "Y"
811
812         layout.operator("clip.set_scale")
813
814         layout.separator()
815
816         layout.operator("clip.track_to_empty")
817         layout.operator("clip.bundles_to_mesh")
818
819
820 class CLIP_MT_track_visibility(Menu):
821     bl_label = "Show/Hide"
822
823     def draw(self, context):
824         layout = self.layout
825
826         layout.operator("clip.hide_tracks_clear", text="Show Hidden")
827         layout.operator("clip.hide_tracks", text="Hide Selected")
828
829         props = layout.operator("clip.hide_tracks", text="Hide Unselected")
830         props.unselected = True
831
832
833 class CLIP_MT_track_transform(Menu):
834     bl_label = "Transform"
835
836     def draw(self, context):
837         layout = self.layout
838
839         layout.operator("transform.translate")
840         layout.operator("transform.resize")
841
842
843 class CLIP_MT_select(Menu):
844     bl_label = "Select"
845
846     def draw(self, context):
847         layout = self.layout
848
849         layout.operator("clip.select_border")
850         layout.operator("clip.select_circle")
851
852         layout.separator()
853
854         layout.operator("clip.select_all", text="Select/Deselect all")
855         layout.operator("clip.select_all", text="Inverse").action = 'INVERT'
856
857         layout.menu("CLIP_MT_select_grouped")
858
859
860 class CLIP_MT_select_grouped(Menu):
861     bl_label = "Select Grouped"
862
863     def draw(self, context):
864         layout = self.layout
865
866         layout.operator_enum("clip.select_grouped", "group")
867
868
869 class CLIP_MT_tracking_specials(Menu):
870     bl_label = "Specials"
871
872     @classmethod
873     def poll(cls, context):
874         return context.space_data.clip
875
876     def draw(self, context):
877         layout = self.layout
878
879         props = layout.operator("clip.disable_markers", text="Enable Markers")
880         props.action = 'ENABLE'
881
882         props = layout.operator("clip.disable_markers", text="Disable markers")
883         props.action = 'DISABLE'
884
885         layout.separator()
886         layout.operator("clip.set_origin")
887
888         layout.separator()
889         layout.operator("clip.hide_tracks")
890         layout.operator("clip.hide_tracks_clear", text="Show Tracks")
891
892         layout.separator()
893         props = layout.operator("clip.lock_tracks", text="Lock Tracks")
894         props.action = 'LOCK'
895
896         props = layout.operator("clip.lock_tracks", text="Unlock Tracks")
897         props.action = 'UNLOCK'
898
899
900 class CLIP_MT_camera_presets(Menu):
901     """Predefined tracking camera intrinsics"""
902     bl_label = "Camera Presets"
903     preset_subdir = "tracking_camera"
904     preset_operator = "script.execute_preset"
905     draw = bpy.types.Menu.draw_preset
906
907
908 class CLIP_MT_track_color_presets(Menu):
909     """Predefined track color"""
910     bl_label = "Color Presets"
911     preset_subdir = "tracking_track_color"
912     preset_operator = "script.execute_preset"
913     draw = bpy.types.Menu.draw_preset
914
915
916 class CLIP_MT_tracking_settings_presets(Menu):
917     """Predefined tracking settings"""
918     bl_label = "Tracking Presets"
919     preset_subdir = "tracking_settings"
920     preset_operator = "script.execute_preset"
921     draw = bpy.types.Menu.draw_preset
922
923
924 class CLIP_MT_track_color_specials(Menu):
925     bl_label = "Track Color Specials"
926
927     def draw(self, context):
928         layout = self.layout
929
930         layout.operator('clip.track_copy_color', icon='COPY_ID')
931
932
933 class CLIP_MT_stabilize_2d_specials(Menu):
934     bl_label = "Track Color Specials"
935
936     def draw(self, context):
937         layout = self.layout
938
939         layout.operator('clip.stabilize_2d_select')
940
941 if __name__ == "__main__":  # only for live edit.
942     bpy.utils.register_module(__name__)