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