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