Fix build error on Windows 32 bit.
[blender-staging.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, UIList
23 from bpy.app.translations import pgettext_iface as iface_
24 from .properties_grease_pencil_common import (
25     GreasePencilDrawingToolsPanel,
26     GreasePencilStrokeEditPanel,
27     GreasePencilStrokeSculptPanel,
28     GreasePencilBrushPanel,
29     GreasePencilBrushCurvesPanel,
30     GreasePencilDataPanel,
31     GreasePencilPaletteColorPanel,
32 )
33
34
35 class CLIP_UL_tracking_objects(UIList):
36     def draw_item(self, context, layout, data, item, icon,
37                   active_data, active_propname, index):
38         # assert(isinstance(item, bpy.types.MovieTrackingObject)
39         tobj = item
40         if self.layout_type in {'DEFAULT', 'COMPACT'}:
41             layout.prop(tobj, "name", text="", emboss=False,
42                         icon='CAMERA_DATA' if tobj.is_camera
43                         else 'OBJECT_DATA')
44         elif self.layout_type == 'GRID':
45             layout.alignment = 'CENTER'
46             layout.label(text="",
47                          icon='CAMERA_DATA' if tobj.is_camera
48                          else 'OBJECT_DATA')
49
50
51 class CLIP_HT_header(Header):
52     bl_space_type = 'CLIP_EDITOR'
53
54     def _draw_tracking(self, context):
55         layout = self.layout
56
57         sc = context.space_data
58         clip = sc.clip
59
60         row = layout.row(align=True)
61         row.template_header()
62
63         CLIP_MT_tracking_editor_menus.draw_collapsible(context, layout)
64
65         row = layout.row()
66         row.template_ID(sc, "clip", open="clip.open")
67
68         if clip:
69             tracking = clip.tracking
70             active_object = tracking.objects.active
71
72             if sc.view == 'CLIP':
73                 layout.prop(sc, "mode", text="")
74                 layout.prop(sc, "view", text="", expand=True)
75                 layout.prop(sc, "pivot_point", text="", icon_only=True)
76
77                 r = active_object.reconstruction
78
79                 if r.is_valid and sc.view == 'CLIP':
80                     layout.label(text="Solve error: %.4f" %
81                                  (r.average_error))
82             elif sc.view == 'GRAPH':
83                 layout.prop(sc, "view", text="", expand=True)
84
85                 row = layout.row(align=True)
86                 row.prop(sc, "show_graph_only_selected", text="")
87                 row.prop(sc, "show_graph_hidden", text="")
88
89                 row = layout.row(align=True)
90
91                 if sc.show_filters:
92                     row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_DOWN',
93                              text="Filters")
94
95                     sub = row.row(align=True)
96                     sub.active = clip.tracking.reconstruction.is_valid
97                     sub.prop(sc, "show_graph_frames", icon='SEQUENCE', text="")
98
99                     row.prop(sc, "show_graph_tracks_motion", icon='IPO', text="")
100                     row.prop(sc, "show_graph_tracks_error", icon='ANIM', text="")
101                 else:
102                     row.prop(sc, "show_filters", icon='DISCLOSURE_TRI_RIGHT',
103                              text="Filters")
104             elif sc.view == 'DOPESHEET':
105                 dopesheet = tracking.dopesheet
106                 layout.prop(sc, "view", text="", expand=True)
107
108                 row = layout.row(align=True)
109                 row.prop(dopesheet, "show_only_selected", text="")
110                 row.prop(dopesheet, "show_hidden", text="")
111
112                 row = layout.row(align=True)
113                 row.prop(dopesheet, "sort_method", text="")
114                 row.prop(dopesheet, "use_invert_sort",
115                          text="Invert", toggle=True)
116         else:
117             layout.prop(sc, "view", text="", expand=True)
118
119     def _draw_masking(self, context):
120         layout = self.layout
121
122         toolsettings = context.tool_settings
123         sc = context.space_data
124         clip = sc.clip
125
126         row = layout.row(align=True)
127         row.template_header()
128
129         CLIP_MT_masking_editor_menus.draw_collapsible(context, layout)
130
131         row = layout.row()
132         row.template_ID(sc, "clip", open="clip.open")
133
134         if clip:
135             layout.prop(sc, "mode", text="")
136
137             row = layout.row()
138             row.template_ID(sc, "mask", new="mask.new")
139
140             layout.prop(sc, "pivot_point", text="", icon_only=True)
141
142             row = layout.row(align=True)
143             row.prop(toolsettings, "use_proportional_edit_mask",
144                      text="", icon_only=True)
145             if toolsettings.use_proportional_edit_mask:
146                 row.prop(toolsettings, "proportional_edit_falloff",
147                          text="", icon_only=True)
148
149     def draw(self, context):
150         layout = self.layout
151
152         sc = context.space_data
153
154         if sc.mode == 'TRACKING':
155             self._draw_tracking(context)
156         else:
157             self._draw_masking(context)
158
159         layout.template_running_jobs()
160
161
162 class CLIP_MT_tracking_editor_menus(Menu):
163     bl_idname = "CLIP_MT_tracking_editor_menus"
164     bl_label = ""
165
166     def draw(self, context):
167         self.draw_menus(self.layout, context)
168
169     @staticmethod
170     def draw_menus(layout, context):
171         sc = context.space_data
172         clip = sc.clip
173
174         layout.menu("CLIP_MT_view")
175
176         if sc.view == 'CLIP':
177             if clip:
178                 layout.menu("CLIP_MT_select")
179                 layout.menu("CLIP_MT_clip")
180                 layout.menu("CLIP_MT_track")
181                 layout.menu("CLIP_MT_reconstruction")
182             else:
183                 layout.menu("CLIP_MT_clip")
184
185
186 class CLIP_MT_masking_editor_menus(Menu):
187
188     bl_idname = "CLIP_MT_masking_editor_menus"
189     bl_label = ""
190
191     def draw(self, context):
192         self.draw_menus(self.layout, context)
193
194     @staticmethod
195     def draw_menus(layout, context):
196         sc = context.space_data
197         clip = sc.clip
198
199         layout.menu("CLIP_MT_view")
200
201         if clip:
202             layout.menu("MASK_MT_select")
203             layout.menu("CLIP_MT_clip")  # XXX - remove?
204             layout.menu("MASK_MT_mask")
205         else:
206             layout.menu("CLIP_MT_clip")  # XXX - remove?
207
208
209 class CLIP_PT_clip_view_panel:
210
211     @classmethod
212     def poll(cls, context):
213         sc = context.space_data
214         clip = sc.clip
215
216         return clip and sc.view == 'CLIP'
217
218
219 class CLIP_PT_tracking_panel:
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' and sc.view == 'CLIP'
227
228
229 class CLIP_PT_reconstruction_panel:
230
231     @classmethod
232     def poll(cls, context):
233         sc = context.space_data
234         clip = sc.clip
235
236         return clip and sc.view == 'CLIP'
237
238
239 class CLIP_PT_tools_clip(Panel):
240     bl_space_type = 'CLIP_EDITOR'
241     bl_region_type = 'TOOLS'
242     bl_label = "Clip"
243     bl_translation_context = bpy.app.translations.contexts.id_movieclip
244     bl_category = "Track"
245
246     @classmethod
247     def poll(cls, context):
248         sc = context.space_data
249         clip = sc.clip
250
251         return clip and sc.view == 'CLIP' and sc.mode != 'MASK'
252
253     def draw(self, context):
254         layout = self.layout
255         col = layout.column(align=True)
256         row = col.row(align=True)
257         row.operator("clip.prefetch", text="Prefetch")
258         row.operator("clip.reload", text="Reload")
259         col.operator("clip.set_scene_frames")
260
261
262 class CLIP_PT_tools_marker(CLIP_PT_tracking_panel, Panel):
263     bl_space_type = 'CLIP_EDITOR'
264     bl_region_type = 'TOOLS'
265     bl_label = "Marker"
266     bl_category = "Track"
267
268     def draw(self, context):
269         layout = self.layout
270
271         # sc = context.space_data
272         # clip = sc.clip
273
274         col = layout.column(align=True)
275         row = col.row(align=True)
276         row.operator("clip.add_marker_at_click", text="Add")
277         row.operator("clip.delete_track", text="Delete")
278         col.operator("clip.detect_features")
279
280
281 class CLIP_PT_tracking_settings(CLIP_PT_tracking_panel, Panel):
282     bl_space_type = 'CLIP_EDITOR'
283     bl_region_type = 'TOOLS'
284     bl_label = "Tracking Settings"
285     bl_category = "Track"
286
287     def draw(self, context):
288
289         sc = context.space_data
290         clip = sc.clip
291         settings = clip.tracking.settings
292         layout = self.layout
293         col = layout.column()
294
295         row = col.row(align=True)
296         label = CLIP_MT_tracking_settings_presets.bl_label
297         row.menu('CLIP_MT_tracking_settings_presets', text=label)
298         row.operator("clip.tracking_settings_preset_add",
299                      text="", icon='ZOOMIN')
300         row.operator("clip.tracking_settings_preset_add",
301                      text="", icon='ZOOMOUT').remove_active = True
302
303         row = col.row(align=True)
304         row.prop(settings, "use_default_red_channel",
305                  text="R", toggle=True)
306         row.prop(settings, "use_default_green_channel",
307                  text="G", toggle=True)
308         row.prop(settings, "use_default_blue_channel",
309                  text="B", toggle=True)
310
311         col.separator()
312
313         sub = col.column(align=True)
314         sub.prop(settings, "default_pattern_size")
315         sub.prop(settings, "default_search_size")
316
317         col.prop(settings, "default_motion_model")
318
319         row = col.row(align=True)
320         row.label(text="Match:")
321         row.prop(settings, "default_pattern_match", text="")
322
323         row = col.row(align=True)
324         row.prop(settings, "use_default_brute")
325         row.prop(settings, "use_default_normalization")
326
327         col.separator()
328         col.operator("clip.track_settings_as_default",
329                      text="Copy From Active Track")
330
331         box = layout.box()
332         row = box.row(align=True)
333         row.prop(settings, "show_default_expanded", text="", emboss=False)
334         row.label(text="Extra Settings")
335
336         if settings.show_default_expanded:
337             col = box.column()
338             row = col.row()
339             row.prop(settings, "use_default_mask")
340
341             sub = col.column(align=True)
342             sub.prop(settings, "default_correlation_min")
343             sub.prop(settings, "default_frames_limit")
344             sub.prop(settings, "default_margin")
345
346             col = box.column()
347             col.prop(settings, "default_weight")
348
349
350 class CLIP_PT_tools_tracking(CLIP_PT_tracking_panel, Panel):
351     bl_space_type = 'CLIP_EDITOR'
352     bl_region_type = 'TOOLS'
353     bl_label = "Track"
354     bl_category = "Track"
355
356     def draw(self, context):
357         layout = self.layout
358
359         row = layout.row(align=True)
360         row.label(text="Track:")
361
362         props = row.operator("clip.track_markers", text="", icon='FRAME_PREV')
363         props.backwards = True
364         props.sequence = False
365         props = row.operator("clip.track_markers", text="",
366                              icon='PLAY_REVERSE')
367         props.backwards = True
368         props.sequence = True
369         props = row.operator("clip.track_markers", text="", icon='PLAY')
370         props.backwards = False
371         props.sequence = True
372         props = row.operator("clip.track_markers", text="", icon='FRAME_NEXT')
373         props.backwards = False
374         props.sequence = False
375
376         col = layout.column(align=True)
377         row = col.row(align=True)
378         row.label(text="Clear:")
379         row.scale_x = 2.0
380
381         props = row.operator("clip.clear_track_path", text="", icon='BACK')
382         props.action = 'UPTO'
383
384         props = row.operator("clip.clear_track_path", text="", icon='FORWARD')
385         props.action = 'REMAINED'
386
387         col = layout.column()
388         row = col.row(align=True)
389         row.label(text="Refine:")
390         row.scale_x = 2.0
391
392         props = row.operator("clip.refine_markers", text="", icon='LOOP_BACK')
393         props.backwards = True
394
395         props = row.operator("clip.refine_markers", text="", icon='LOOP_FORWARDS')
396         props.backwards = False
397
398         col = layout.column(align=True)
399         row = col.row(align=True)
400         row.label(text="Merge:")
401         row.operator("clip.join_tracks", text="Join Tracks")
402
403
404 class CLIP_PT_tools_plane_tracking(CLIP_PT_tracking_panel, Panel):
405     bl_space_type = 'CLIP_EDITOR'
406     bl_region_type = 'TOOLS'
407     bl_label = "Plane Track"
408     bl_options = {'DEFAULT_CLOSED'}
409     bl_category = "Solve"
410
411     def draw(self, context):
412         layout = self.layout
413         layout.operator("clip.create_plane_track")
414
415
416 class CLIP_PT_tools_solve(CLIP_PT_tracking_panel, Panel):
417     bl_space_type = 'CLIP_EDITOR'
418     bl_region_type = 'TOOLS'
419     bl_label = "Solve"
420     bl_category = "Solve"
421
422     def draw(self, context):
423         layout = self.layout
424
425         clip = context.space_data.clip
426         tracking = clip.tracking
427         settings = tracking.settings
428         tracking_object = tracking.objects.active
429
430         col = layout.column()
431         row = col.row()
432         row.prop(settings, "use_tripod_solver", text="Tripod")
433         sub = row.row()
434         sub.active = not settings.use_tripod_solver
435         sub.prop(settings, "use_keyframe_selection", text="Keyframe")
436
437         col = layout.column(align=True)
438         col.active = (not settings.use_tripod_solver and
439                       not settings.use_keyframe_selection)
440         col.prop(tracking_object, "keyframe_a")
441         col.prop(tracking_object, "keyframe_b")
442
443         col = layout.column(align=True)
444         col.active = tracking_object.is_camera
445         row = col.row(align=True)
446         row.label(text="Refine:")
447         row.prop(settings, "refine_intrinsics", text="")
448
449         col = layout.column(align=True)
450         col.scale_y = 2.0
451
452         col.operator("clip.solve_camera",
453                      text="Solve Camera Motion" if tracking_object.is_camera
454                      else "Solve Object Motion")
455
456
457 class CLIP_PT_tools_cleanup(CLIP_PT_tracking_panel, Panel):
458     bl_space_type = 'CLIP_EDITOR'
459     bl_region_type = 'TOOLS'
460     bl_label = "Clean up"
461     bl_options = {'DEFAULT_CLOSED'}
462     bl_category = "Solve"
463
464     def draw(self, context):
465         layout = self.layout
466         clip = context.space_data.clip
467         settings = clip.tracking.settings
468
469         layout.operator("clip.clean_tracks")
470
471         layout.prop(settings, "clean_frames", text="Frames")
472         layout.prop(settings, "clean_error", text="Error")
473         layout.prop(settings, "clean_action", text="")
474         layout.separator()
475         layout.operator("clip.filter_tracks")
476
477
478 class CLIP_PT_tools_geometry(CLIP_PT_tracking_panel, Panel):
479     bl_space_type = 'CLIP_EDITOR'
480     bl_region_type = 'TOOLS'
481     bl_label = "Geometry"
482     bl_options = {'DEFAULT_CLOSED'}
483     bl_category = "Solve"
484
485     def draw(self, context):
486         layout = self.layout
487
488         layout.operator("clip.bundles_to_mesh")
489         layout.operator("clip.track_to_empty")
490
491
492 class CLIP_PT_tools_orientation(CLIP_PT_tracking_panel, Panel):
493     bl_space_type = 'CLIP_EDITOR'
494     bl_region_type = 'TOOLS'
495     bl_label = "Orientation"
496     bl_category = "Solve"
497
498     def draw(self, context):
499         sc = context.space_data
500         layout = self.layout
501         settings = sc.clip.tracking.settings
502
503         col = layout.column(align=True)
504         row = col.row(align=True)
505         row.operator("clip.set_plane", text="Floor").plane = 'FLOOR'
506         row.operator("clip.set_plane", text="Wall").plane = 'WALL'
507
508         col.operator("clip.set_origin")
509
510         row = col.row(align=True)
511         row.operator("clip.set_axis", text="Set X Axis").axis = 'X'
512         row.operator("clip.set_axis", text="Set Y Axis").axis = 'Y'
513
514         layout.separator()
515
516         col = layout.column()
517         row = col.row(align=True)
518         row.operator("clip.set_scale")
519         row.operator("clip.apply_solution_scale", text="Apply Scale")
520
521         col.prop(settings, "distance")
522
523
524 class CLIP_PT_tools_object(CLIP_PT_reconstruction_panel, Panel):
525     bl_space_type = 'CLIP_EDITOR'
526     bl_region_type = 'TOOLS'
527     bl_label = "Object"
528     bl_category = "Solve"
529
530     @classmethod
531     def poll(cls, context):
532         if CLIP_PT_reconstruction_panel.poll(context):
533             sc = context.space_data
534             clip = sc.clip
535
536             tracking_object = clip.tracking.objects.active
537
538             return not tracking_object.is_camera
539
540         return False
541
542     def draw(self, context):
543         layout = self.layout
544
545         sc = context.space_data
546         clip = sc.clip
547         tracking_object = clip.tracking.objects.active
548         settings = sc.clip.tracking.settings
549
550         col = layout.column()
551
552         col.prop(tracking_object, "scale")
553
554         col.separator()
555
556         col.operator("clip.set_solution_scale", text="Set Scale")
557         col.prop(settings, "object_distance")
558
559
560 class CLIP_PT_objects(CLIP_PT_clip_view_panel, Panel):
561     bl_space_type = 'CLIP_EDITOR'
562     bl_region_type = 'UI'
563     bl_label = "Objects"
564     bl_options = {'DEFAULT_CLOSED'}
565
566     def draw(self, context):
567         layout = self.layout
568
569         sc = context.space_data
570         tracking = sc.clip.tracking
571
572         row = layout.row()
573         row.template_list("CLIP_UL_tracking_objects", "", tracking, "objects",
574                           tracking, "active_object_index", rows=1)
575
576         sub = row.column(align=True)
577
578         sub.operator("clip.tracking_object_new", icon='ZOOMIN', text="")
579         sub.operator("clip.tracking_object_remove", icon='ZOOMOUT', text="")
580
581
582 class CLIP_PT_track(CLIP_PT_tracking_panel, Panel):
583     bl_space_type = 'CLIP_EDITOR'
584     bl_region_type = 'UI'
585     bl_label = "Track"
586
587     def draw(self, context):
588         layout = self.layout
589
590         sc = context.space_data
591         clip = context.space_data.clip
592         act_track = clip.tracking.tracks.active
593
594         if not act_track:
595             layout.active = False
596             layout.label(text="No active track")
597             return
598
599         row = layout.row()
600         row.prop(act_track, "name", text="")
601
602         sub = row.row(align=True)
603
604         sub.template_marker(sc, "clip", sc.clip_user, act_track, True)
605
606         icon = 'LOCKED' if act_track.lock else 'UNLOCKED'
607         sub.prop(act_track, "lock", text="", icon=icon)
608
609         layout.template_track(sc, "scopes")
610
611         row = layout.row(align=True)
612         sub = row.row(align=True)
613         sub.prop(act_track, "use_red_channel", text="R", toggle=True)
614         sub.prop(act_track, "use_green_channel", text="G", toggle=True)
615         sub.prop(act_track, "use_blue_channel", text="B", toggle=True)
616
617         row.separator()
618
619         row.prop(act_track, "use_grayscale_preview", text="B/W", toggle=True)
620
621         row.separator()
622         row.prop(act_track, "use_alpha_preview",
623                  text="", toggle=True, icon='IMAGE_ALPHA')
624
625         layout.prop(act_track, "weight")
626         layout.prop(act_track, "weight_stab")
627
628         if act_track.has_bundle:
629             label_text = "Average Error: %.4f" % (act_track.average_error)
630             layout.label(text=label_text)
631
632         layout.separator()
633
634         row = layout.row(align=True)
635         label = bpy.types.CLIP_MT_track_color_presets.bl_label
636         row.menu('CLIP_MT_track_color_presets', text=label)
637         row.menu('CLIP_MT_track_color_specials', text="", icon='DOWNARROW_HLT')
638         row.operator("clip.track_color_preset_add", text="", icon='ZOOMIN')
639         row.operator("clip.track_color_preset_add",
640                      text="", icon='ZOOMOUT').remove_active = True
641
642         row = layout.row()
643         row.prop(act_track, "use_custom_color")
644         if act_track.use_custom_color:
645             row.prop(act_track, "color", text="")
646
647
648 class CLIP_PT_plane_track(CLIP_PT_tracking_panel, Panel):
649     bl_space_type = 'CLIP_EDITOR'
650     bl_region_type = 'UI'
651     bl_label = "Plane Track"
652     bl_options = {'DEFAULT_CLOSED'}
653
654     def draw(self, context):
655         layout = self.layout
656
657         clip = context.space_data.clip
658         active_track = clip.tracking.plane_tracks.active
659
660         if not active_track:
661             layout.active = False
662             layout.label(text="No active plane track")
663             return
664
665         layout.prop(active_track, "name")
666         layout.prop(active_track, "use_auto_keying")
667         layout.prop(active_track, "image")
668
669         row = layout.row()
670         row.active = active_track.image is not None
671         row.prop(active_track, "image_opacity", text="Opacity")
672
673
674 class CLIP_PT_track_settings(CLIP_PT_tracking_panel, Panel):
675     bl_space_type = 'CLIP_EDITOR'
676     bl_region_type = 'UI'
677     bl_label = "Tracking Settings"
678     bl_options = {'DEFAULT_CLOSED'}
679
680     def draw(self, context):
681         layout = self.layout
682
683         clip = context.space_data.clip
684         settings = clip.tracking.settings
685
686         col = layout.column()
687
688         active = clip.tracking.tracks.active
689         if active:
690             col.prop(active, "motion_model")
691             col.prop(active, "pattern_match", text="Match")
692             col = layout.column()
693             row = col.row(align=True)
694             row.prop(active, "use_brute")
695             row.prop(active, "use_normalization")
696
697             box = layout.box()
698             row = box.row(align=True)
699             row.prop(settings, "show_extra_expanded", text="", emboss=False)
700             row.label(text="Extra Settings")
701
702             if settings.show_extra_expanded:
703                 col = box.column()
704                 row = col.row()
705                 row.prop(active, "use_mask")
706
707                 sub = col.column(align=True)
708                 sub.prop(active, "correlation_min")
709                 sub.prop(active, "frames_limit")
710                 sub.prop(active, "margin")
711                 sub.separator()
712                 sub.prop(settings, "speed")
713
714
715 class CLIP_PT_tracking_camera(Panel):
716     bl_space_type = 'CLIP_EDITOR'
717     bl_region_type = 'UI'
718     bl_label = "Camera"
719     bl_options = {'DEFAULT_CLOSED'}
720
721     @classmethod
722     def poll(cls, context):
723         if CLIP_PT_clip_view_panel.poll(context):
724             sc = context.space_data
725
726             return sc.mode == 'TRACKING' and sc.clip
727
728         return False
729
730     def draw(self, context):
731         layout = self.layout
732
733         sc = context.space_data
734         clip = sc.clip
735
736         row = layout.row(align=True)
737         label = bpy.types.CLIP_MT_camera_presets.bl_label
738         row.menu('CLIP_MT_camera_presets', text=label)
739         row.operator("clip.camera_preset_add", text="", icon='ZOOMIN')
740         row.operator("clip.camera_preset_add", text="",
741                      icon='ZOOMOUT').remove_active = True
742
743         col = layout.column(align=True)
744         col.label(text="Sensor:")
745         col.prop(clip.tracking.camera, "sensor_width", text="Width")
746         col.prop(clip.tracking.camera, "pixel_aspect")
747
748         col = layout.column()
749         col.label(text="Optical Center:")
750         row = col.row()
751         row.prop(clip.tracking.camera, "principal", text="")
752         col.operator("clip.set_center_principal", text="Center")
753
754
755 class CLIP_PT_tracking_lens(Panel):
756     bl_space_type = 'CLIP_EDITOR'
757     bl_region_type = 'UI'
758     bl_label = "Lens"
759     bl_options = {'DEFAULT_CLOSED'}
760
761     @classmethod
762     def poll(cls, context):
763         if CLIP_PT_clip_view_panel.poll(context):
764             sc = context.space_data
765
766             return sc.mode == 'TRACKING' and sc.clip
767
768         return False
769
770     def draw(self, context):
771         layout = self.layout
772
773         sc = context.space_data
774         clip = sc.clip
775
776         row = layout.row(align=True)
777         sub = row.split(percentage=0.65, align=True)
778         if clip.tracking.camera.units == 'MILLIMETERS':
779             sub.prop(clip.tracking.camera, "focal_length")
780         else:
781             sub.prop(clip.tracking.camera, "focal_length_pixels")
782         sub.prop(clip.tracking.camera, "units", text="")
783
784         col = layout.column()
785         col.label(text="Lens Distortion:")
786         camera = clip.tracking.camera
787         col.prop(camera, "distortion_model", text="")
788         if camera.distortion_model == 'POLYNOMIAL':
789             col = layout.column(align=True)
790             col.prop(camera, "k1")
791             col.prop(camera, "k2")
792             col.prop(camera, "k3")
793         elif camera.distortion_model == 'DIVISION':
794             col = layout.column(align=True)
795             col.prop(camera, "division_k1")
796             col.prop(camera, "division_k2")
797
798
799 class CLIP_PT_display(CLIP_PT_clip_view_panel, Panel):
800     bl_space_type = 'CLIP_EDITOR'
801     bl_region_type = 'UI'
802     bl_label = "Display"
803
804     def draw(self, context):
805         layout = self.layout
806         sc = context.space_data
807
808         row = layout.row(align=True)
809
810         sub = row.row(align=True)
811         sub.prop(sc, "show_red_channel", text="R", toggle=True)
812         sub.prop(sc, "show_green_channel", text="G", toggle=True)
813         sub.prop(sc, "show_blue_channel", text="B", toggle=True)
814         row.separator()
815         row.prop(sc, "use_grayscale_preview", text="B/W", toggle=True)
816         row.separator()
817         row.prop(sc, "use_mute_footage", text="", icon='VISIBLE_IPO_ON', toggle=True)
818
819         col = layout.column(align=True)
820         col.prop(sc.clip_user, "use_render_undistorted", text="Render Undistorted")
821         col.prop(sc, "lock_selection", text="Lock to Selection")
822         col.prop(sc, "show_stable", text="Display Stabilization")
823         if sc.view == 'GRAPH':
824             col.prop(sc, "lock_time_cursor")
825         row = col.row(align=True)
826         row.prop(sc, "show_grid", text="Grid")
827         row.prop(sc, "use_manual_calibration", text="Calibration")
828
829         clip = sc.clip
830         if clip:
831             col.label(text="Display Aspect Ratio:")
832             row = col.row()
833             row.prop(clip, "display_aspect", text="")
834
835
836 class CLIP_PT_marker_display(CLIP_PT_clip_view_panel, Panel):
837     bl_space_type = 'CLIP_EDITOR'
838     bl_region_type = 'UI'
839     bl_label = "Marker Display"
840
841     @classmethod
842     def poll(cls, context):
843         sc = context.space_data
844
845         return sc.mode != 'MASK'
846
847     def draw(self, context):
848         layout = self.layout
849         sc = context.space_data
850
851         col = layout.column(align=True)
852         row = col.row(align=True)
853         row.prop(sc, "show_marker_pattern", text="Pattern")
854         row.prop(sc, "show_marker_search", text="Search")
855
856         row = col.row(align=True)
857         row.active = sc.show_track_path
858         row.prop(sc, "show_track_path", text="Path")
859         row.prop(sc, "path_length", text="Length")
860
861         col = layout.column(align=True)
862         row = col.row(align=True)
863         row.prop(sc, "show_disabled", "Disabled")
864         row.prop(sc, "show_names", text="Info")
865
866         row = col.row(align=True)
867         if sc.mode != 'MASK':
868             row.prop(sc, "show_bundles", text="3D Markers")
869         row.prop(sc, "show_tiny_markers", text="Thin")
870
871
872 class CLIP_PT_marker(CLIP_PT_tracking_panel, Panel):
873     bl_space_type = 'CLIP_EDITOR'
874     bl_region_type = 'UI'
875     bl_label = "Marker"
876     bl_options = {'DEFAULT_CLOSED'}
877
878     def draw(self, context):
879         layout = self.layout
880         sc = context.space_data
881         clip = context.space_data.clip
882         act_track = clip.tracking.tracks.active
883
884         if act_track:
885             layout.template_marker(sc, "clip", sc.clip_user, act_track, False)
886         else:
887             layout.active = False
888             layout.label(text="No active track")
889
890
891 class CLIP_PT_stabilization(CLIP_PT_reconstruction_panel, Panel):
892     bl_space_type = 'CLIP_EDITOR'
893     bl_region_type = 'UI'
894     bl_label = "2D Stabilization"
895     bl_category = "Stabilization"
896     bl_options = {'DEFAULT_CLOSED'}
897
898     @classmethod
899     def poll(cls, context):
900         if CLIP_PT_clip_view_panel.poll(context):
901             sc = context.space_data
902
903             return sc.mode == 'TRACKING' and sc.clip
904
905         return False
906
907     def draw_header(self, context):
908         stab = context.space_data.clip.tracking.stabilization
909
910         self.layout.prop(stab, "use_2d_stabilization", text="")
911
912     def draw(self, context):
913         tracking = context.space_data.clip.tracking
914         stab = tracking.stabilization
915
916         layout = self.layout
917         layout.active = stab.use_2d_stabilization
918
919         layout.prop(stab, "anchor_frame")
920
921         row = layout.row(align=True)
922         row.prop(stab, "use_stabilize_rotation", text="Rotation", toggle=True)
923         sub = row.row(align=True)
924         sub.active = stab.use_stabilize_rotation
925         sub.prop(stab, "use_stabilize_scale", text="Scale", toggle=True)
926
927         box = layout.box()
928         row = box.row(align=True)
929         row.prop(stab, "show_tracks_expanded", text="", emboss=False)
930
931         if not stab.show_tracks_expanded:
932             row.label(text="Tracks For Stabilization")
933         else:
934             row.label(text="Tracks For Location")
935             row = box.row()
936             row.template_list("UI_UL_list", "stabilization_tracks", stab, "tracks",
937                               stab, "active_track_index", rows=2)
938
939             sub = row.column(align=True)
940
941             sub.operator("clip.stabilize_2d_add", icon='ZOOMIN', text="")
942             sub.operator("clip.stabilize_2d_remove", icon='ZOOMOUT', text="")
943
944             sub.menu('CLIP_MT_stabilize_2d_specials', text="",
945                      icon='DOWNARROW_HLT')
946
947             # Usually we don't hide things from iterface, but here every pixel of
948             # vertical space is precious.
949             if stab.use_stabilize_rotation:
950                 box.label(text="Tracks For Rotation / Scale")
951                 row = box.row()
952                 row.template_list("UI_UL_list", "stabilization_rotation_tracks",
953                                   stab, "rotation_tracks",
954                                   stab, "active_rotation_track_index", rows=2)
955
956                 sub = row.column(align=True)
957
958                 sub.operator("clip.stabilize_2d_rotation_add", icon='ZOOMIN', text="")
959                 sub.operator("clip.stabilize_2d_rotation_remove", icon='ZOOMOUT', text="")
960
961                 sub.menu('CLIP_MT_stabilize_2d_rotation_specials', text="",
962                          icon='DOWNARROW_HLT')
963
964         row = layout.row()
965         row.prop(stab, "use_autoscale")
966         sub = row.row()
967         sub.active = stab.use_autoscale
968         sub.prop(stab, "scale_max", text="Max")
969
970         col = layout.column(align=True)
971         row = col.row(align=True)
972         # Hrm, how to make it more obvious label?
973         row.prop(stab, "target_position", text="")
974         col.prop(stab, "target_rotation")
975         row = col.row(align=True)
976         row.prop(stab, "target_scale")
977         row.active = not stab.use_autoscale
978
979         col = layout.column(align=True)
980         col.prop(stab, "influence_location")
981         sub = col.column(align=True)
982         sub.active = stab.use_stabilize_rotation
983         sub.prop(stab, "influence_rotation")
984         sub.prop(stab, "influence_scale")
985
986         layout.prop(stab, "filter_type")
987
988
989 class CLIP_PT_proxy(CLIP_PT_clip_view_panel, Panel):
990     bl_space_type = 'CLIP_EDITOR'
991     bl_region_type = 'UI'
992     bl_label = "Proxy/Timecode"
993     bl_options = {'DEFAULT_CLOSED'}
994
995     def draw_header(self, context):
996         sc = context.space_data
997
998         self.layout.prop(sc.clip, "use_proxy", text="")
999
1000     def draw(self, context):
1001         layout = self.layout
1002
1003         sc = context.space_data
1004         clip = sc.clip
1005
1006         col = layout.column()
1007         col.active = clip.use_proxy
1008
1009         col.label(text="Build Original:")
1010
1011         row = col.row(align=True)
1012         row.prop(clip.proxy, "build_25", toggle=True)
1013         row.prop(clip.proxy, "build_50", toggle=True)
1014         row.prop(clip.proxy, "build_75", toggle=True)
1015         row.prop(clip.proxy, "build_100", toggle=True)
1016
1017         col.label(text="Build Undistorted:")
1018
1019         row = col.row(align=True)
1020         row.prop(clip.proxy, "build_undistorted_25", toggle=True)
1021         row.prop(clip.proxy, "build_undistorted_50", toggle=True)
1022         row.prop(clip.proxy, "build_undistorted_75", toggle=True)
1023         row.prop(clip.proxy, "build_undistorted_100", toggle=True)
1024
1025         col.prop(clip.proxy, "quality")
1026
1027         col.prop(clip, "use_proxy_custom_directory")
1028         if clip.use_proxy_custom_directory:
1029             col.prop(clip.proxy, "directory")
1030
1031         col.operator("clip.rebuild_proxy",
1032                      text="Build Proxy / Timecode" if clip.source == 'MOVIE'
1033                                                    else "Build Proxy")
1034
1035         if clip.source == 'MOVIE':
1036             col2 = col.column()
1037
1038             col2.label(text="Use Timecode Index:")
1039             col2.prop(clip.proxy, "timecode", text="")
1040
1041         col2 = col.column()
1042         col2.label(text="Proxy Render Size:")
1043
1044         col.prop(sc.clip_user, "proxy_render_size", text="")
1045
1046
1047 # -----------------------------------------------------------------------------
1048 # Mask (similar code in space_image.py, keep in sync)
1049
1050 from .properties_mask_common import (
1051     MASK_PT_mask,
1052     MASK_PT_layers,
1053     MASK_PT_spline,
1054     MASK_PT_point,
1055     MASK_PT_display,
1056     MASK_PT_tools,
1057     MASK_PT_transforms,
1058     MASK_PT_add,
1059 )
1060
1061
1062 class CLIP_PT_mask_layers(MASK_PT_layers, Panel):
1063     bl_space_type = 'CLIP_EDITOR'
1064     bl_region_type = 'UI'
1065
1066
1067 class CLIP_PT_mask_display(MASK_PT_display, Panel):
1068     bl_space_type = 'CLIP_EDITOR'
1069     bl_region_type = 'UI'
1070
1071
1072 class CLIP_PT_active_mask_spline(MASK_PT_spline, Panel):
1073     bl_space_type = 'CLIP_EDITOR'
1074     bl_region_type = 'UI'
1075
1076
1077 class CLIP_PT_active_mask_point(MASK_PT_point, Panel):
1078     bl_space_type = 'CLIP_EDITOR'
1079     bl_region_type = 'UI'
1080
1081
1082 class CLIP_PT_mask(MASK_PT_mask, Panel):
1083     bl_space_type = 'CLIP_EDITOR'
1084     bl_region_type = 'UI'
1085
1086
1087 class CLIP_PT_tools_mask_add(MASK_PT_add, Panel):
1088     bl_space_type = 'CLIP_EDITOR'
1089     bl_region_type = 'TOOLS'
1090
1091
1092 class CLIP_PT_tools_mask_transforms(MASK_PT_transforms, Panel):
1093     bl_space_type = 'CLIP_EDITOR'
1094     bl_region_type = 'TOOLS'
1095
1096
1097 class CLIP_PT_tools_mask(MASK_PT_tools, Panel):
1098     bl_space_type = 'CLIP_EDITOR'
1099     bl_region_type = 'TOOLS'
1100
1101 # --- end mask ---
1102
1103
1104 class CLIP_PT_footage(CLIP_PT_clip_view_panel, Panel):
1105     bl_space_type = 'CLIP_EDITOR'
1106     bl_region_type = 'UI'
1107     bl_label = "Footage Settings"
1108     bl_options = {'DEFAULT_CLOSED'}
1109
1110     def draw(self, context):
1111         layout = self.layout
1112
1113         sc = context.space_data
1114         clip = sc.clip
1115
1116         col = layout.column()
1117         col.template_movieclip(sc, "clip", compact=True)
1118         col.prop(clip, "frame_start")
1119         col.prop(clip, "frame_offset")
1120
1121
1122 class CLIP_PT_footage_info(CLIP_PT_clip_view_panel, Panel):
1123     bl_space_type = 'CLIP_EDITOR'
1124     bl_region_type = 'UI'
1125     bl_label = "Footage Information"
1126     bl_options = {'DEFAULT_CLOSED'}
1127
1128     def draw(self, context):
1129         layout = self.layout
1130
1131         sc = context.space_data
1132
1133         col = layout.column()
1134         col.template_movieclip_information(sc, "clip", sc.clip_user)
1135
1136
1137 class CLIP_PT_tools_scenesetup(Panel):
1138     bl_space_type = 'CLIP_EDITOR'
1139     bl_region_type = 'TOOLS'
1140     bl_label = "Scene Setup"
1141     bl_translation_context = bpy.app.translations.contexts.id_movieclip
1142     bl_category = "Solve"
1143
1144     @classmethod
1145     def poll(cls, context):
1146         sc = context.space_data
1147         clip = sc.clip
1148
1149         return clip and sc.view == 'CLIP' and sc.mode != 'MASK'
1150
1151     def draw(self, context):
1152         layout = self.layout
1153
1154         layout.operator("clip.set_viewport_background")
1155         layout.operator("clip.setup_tracking_scene")
1156
1157
1158 # Grease Pencil properties
1159 class CLIP_PT_grease_pencil(GreasePencilDataPanel, CLIP_PT_clip_view_panel, Panel):
1160     bl_space_type = 'CLIP_EDITOR'
1161     bl_region_type = 'UI'
1162     bl_options = {'DEFAULT_CLOSED'}
1163
1164     # NOTE: this is just a wrapper around the generic GP Panel
1165     # But, this should only be visible in "clip" view
1166
1167
1168 # Grease Pencil palette colors
1169 class CLIP_PT_grease_pencil_palettecolor(GreasePencilPaletteColorPanel, CLIP_PT_clip_view_panel, Panel):
1170     bl_space_type = 'CLIP_EDITOR'
1171     bl_region_type = 'UI'
1172     bl_options = {'DEFAULT_CLOSED'}
1173
1174     # NOTE: this is just a wrapper around the generic GP Panel
1175     # But, this should only be visible in "clip" view
1176
1177
1178 # Grease Pencil drawing tools
1179 class CLIP_PT_tools_grease_pencil_draw(GreasePencilDrawingToolsPanel, Panel):
1180     bl_space_type = 'CLIP_EDITOR'
1181
1182
1183 # Grease Pencil stroke editing tools
1184 class CLIP_PT_tools_grease_pencil_edit(GreasePencilStrokeEditPanel, Panel):
1185     bl_space_type = 'CLIP_EDITOR'
1186
1187
1188 # Grease Pencil stroke sculpting tools
1189 class CLIP_PT_tools_grease_pencil_sculpt(GreasePencilStrokeSculptPanel, Panel):
1190     bl_space_type = 'CLIP_EDITOR'
1191
1192
1193 # Grease Pencil drawing brushes
1194 class CLIP_PT_tools_grease_pencil_brush(GreasePencilBrushPanel, Panel):
1195     bl_space_type = 'CLIP_EDITOR'
1196
1197
1198 # Grease Pencil drawing curves
1199 class CLIP_PT_tools_grease_pencil_brushcurves(GreasePencilBrushCurvesPanel, Panel):
1200     bl_space_type = 'CLIP_EDITOR'
1201
1202 class CLIP_MT_view(Menu):
1203     bl_label = "View"
1204
1205     def draw(self, context):
1206         layout = self.layout
1207
1208         sc = context.space_data
1209
1210         if sc.view == 'CLIP':
1211             layout.operator("clip.properties", icon='MENU_PANEL')
1212             layout.operator("clip.tools", icon='MENU_PANEL')
1213             layout.separator()
1214
1215             layout.operator("clip.view_selected")
1216             layout.operator("clip.view_all")
1217             layout.operator("clip.view_all", text="View Fit").fit_view = True
1218
1219             layout.separator()
1220             layout.operator("clip.view_zoom_in")
1221             layout.operator("clip.view_zoom_out")
1222
1223             layout.separator()
1224             layout.prop(sc, "show_metadata")
1225             layout.separator()
1226
1227             ratios = ((1, 8), (1, 4), (1, 2), (1, 1), (2, 1), (4, 1), (8, 1))
1228
1229             text = iface_("Zoom %d:%d")
1230             for a, b in ratios:
1231                 layout.operator("clip.view_zoom_ratio",
1232                                 text=text % (a, b),
1233                                 translate=False).ratio = a / b
1234         else:
1235             if sc.view == 'GRAPH':
1236                 layout.operator_context = 'INVOKE_REGION_PREVIEW'
1237                 layout.operator("clip.graph_center_current_frame")
1238                 layout.operator("clip.graph_view_all")
1239                 layout.operator_context = 'INVOKE_DEFAULT'
1240
1241             layout.prop(sc, "show_seconds")
1242             layout.prop(sc, "show_locked_time")
1243
1244         layout.separator()
1245         layout.operator("screen.area_dupli")
1246         layout.operator("screen.screen_full_area")
1247         layout.operator("screen.screen_full_area", text="Toggle Fullscreen Area").use_hide_panels = True
1248
1249
1250 class CLIP_MT_clip(Menu):
1251     bl_label = "Clip"
1252     bl_translation_context = bpy.app.translations.contexts.id_movieclip
1253
1254     def draw(self, context):
1255         layout = self.layout
1256
1257         sc = context.space_data
1258         clip = sc.clip
1259
1260         layout.operator("clip.open")
1261
1262         if clip:
1263             layout.operator("clip.prefetch")
1264             layout.operator("clip.reload")
1265             layout.menu("CLIP_MT_proxy")
1266
1267
1268 class CLIP_MT_proxy(Menu):
1269     bl_label = "Proxy"
1270
1271     def draw(self, context):
1272         layout = self.layout
1273
1274         layout.operator("clip.rebuild_proxy")
1275         layout.operator("clip.delete_proxy")
1276
1277
1278 class CLIP_MT_track(Menu):
1279     bl_label = "Track"
1280
1281     def draw(self, context):
1282         layout = self.layout
1283
1284         layout.operator("clip.clear_solution")
1285         layout.operator("clip.solve_camera")
1286
1287         layout.separator()
1288         props = layout.operator("clip.clear_track_path", text="Clear After")
1289         props.clear_active = False
1290         props.action = 'REMAINED'
1291
1292         props = layout.operator("clip.clear_track_path", text="Clear Before")
1293         props.clear_active = False
1294         props.action = 'UPTO'
1295
1296         props = layout.operator("clip.clear_track_path", text="Clear Track Path")
1297         props.clear_active = False
1298         props.action = 'ALL'
1299
1300         layout.separator()
1301         layout.operator("clip.join_tracks")
1302
1303         layout.separator()
1304         layout.operator("clip.clean_tracks")
1305
1306         layout.separator()
1307         layout.operator("clip.copy_tracks")
1308         layout.operator("clip.paste_tracks")
1309
1310         layout.separator()
1311         props = layout.operator("clip.track_markers", text="Track Frame Backwards")
1312         props.backwards = True
1313         props.sequence = False
1314
1315         props = layout.operator("clip.track_markers", text="Track Backwards")
1316         props.backwards = True
1317         props.sequence = True
1318
1319         props = layout.operator("clip.track_markers", text="Track Forwards")
1320         props.backwards = False
1321         props.sequence = True
1322
1323         props = layout.operator("clip.track_markers", text="Track Frame Forwards")
1324         props.backwards = False
1325         props.sequence = False
1326
1327         layout.separator()
1328         layout.operator("clip.delete_track")
1329         layout.operator("clip.delete_marker")
1330
1331         layout.separator()
1332         layout.operator("clip.add_marker_move")
1333
1334         layout.separator()
1335         layout.menu("CLIP_MT_track_visibility")
1336         layout.menu("CLIP_MT_track_transform")
1337
1338
1339 class CLIP_MT_reconstruction(Menu):
1340     bl_label = "Reconstruction"
1341
1342     def draw(self, context):
1343         layout = self.layout
1344
1345         layout.operator("clip.set_origin")
1346         layout.operator("clip.set_plane", text="Set Floor").plane = 'FLOOR'
1347         layout.operator("clip.set_plane", text="Set Wall").plane = 'WALL'
1348
1349         layout.operator("clip.set_axis", text="Set X Axis").axis = 'X'
1350         layout.operator("clip.set_axis", text="Set Y Axis").axis = 'Y'
1351
1352         layout.operator("clip.set_scale")
1353
1354         layout.separator()
1355
1356         layout.operator("clip.track_to_empty")
1357         layout.operator("clip.bundles_to_mesh")
1358
1359
1360 class CLIP_MT_track_visibility(Menu):
1361     bl_label = "Show/Hide"
1362
1363     def draw(self, context):
1364         layout = self.layout
1365
1366         layout.operator("clip.hide_tracks_clear", text="Show Hidden")
1367         layout.operator("clip.hide_tracks", text="Hide Selected").unselected = False
1368         layout.operator("clip.hide_tracks", text="Hide Unselected").unselected = True
1369
1370
1371 class CLIP_MT_track_transform(Menu):
1372     bl_label = "Transform"
1373
1374     def draw(self, context):
1375         layout = self.layout
1376
1377         layout.operator("transform.translate")
1378         layout.operator("transform.resize")
1379
1380
1381 class CLIP_MT_select(Menu):
1382     bl_label = "Select"
1383
1384     def draw(self, context):
1385         layout = self.layout
1386
1387         layout.operator("clip.select_border")
1388         layout.operator("clip.select_circle")
1389
1390         layout.separator()
1391
1392         layout.operator("clip.select_all"
1393                         ).action = 'TOGGLE'
1394         layout.operator("clip.select_all",
1395                         text="Inverse").action = 'INVERT'
1396
1397         layout.menu("CLIP_MT_select_grouped")
1398
1399
1400 class CLIP_MT_select_grouped(Menu):
1401     bl_label = "Select Grouped"
1402
1403     def draw(self, context):
1404         layout = self.layout
1405
1406         layout.operator_enum("clip.select_grouped", "group")
1407
1408
1409 class CLIP_MT_tracking_specials(Menu):
1410     bl_label = "Specials"
1411
1412     @classmethod
1413     def poll(cls, context):
1414         return context.space_data.clip
1415
1416     def draw(self, context):
1417         layout = self.layout
1418
1419         layout.operator("clip.disable_markers",
1420                         text="Enable Markers").action = 'ENABLE'
1421
1422         layout.operator("clip.disable_markers",
1423                         text="Disable Markers").action = 'DISABLE'
1424
1425         layout.separator()
1426         layout.operator("clip.set_origin")
1427
1428         layout.separator()
1429         layout.operator("clip.hide_tracks")
1430         layout.operator("clip.hide_tracks_clear", text="Show Tracks")
1431
1432         layout.separator()
1433         layout.operator("clip.lock_tracks", text="Lock Tracks").action = 'LOCK'
1434
1435         layout.operator("clip.lock_tracks",
1436                         text="Unlock Tracks").action = 'UNLOCK'
1437
1438
1439 class CLIP_MT_camera_presets(Menu):
1440     """Predefined tracking camera intrinsics"""
1441     bl_label = "Camera Presets"
1442     preset_subdir = "tracking_camera"
1443     preset_operator = "script.execute_preset"
1444     draw = Menu.draw_preset
1445
1446
1447 class CLIP_MT_track_color_presets(Menu):
1448     """Predefined track color"""
1449     bl_label = "Color Presets"
1450     preset_subdir = "tracking_track_color"
1451     preset_operator = "script.execute_preset"
1452     draw = Menu.draw_preset
1453
1454
1455 class CLIP_MT_tracking_settings_presets(Menu):
1456     """Predefined tracking settings"""
1457     bl_label = "Tracking Presets"
1458     preset_subdir = "tracking_settings"
1459     preset_operator = "script.execute_preset"
1460     draw = Menu.draw_preset
1461
1462
1463 class CLIP_MT_track_color_specials(Menu):
1464     bl_label = "Track Color Specials"
1465
1466     def draw(self, context):
1467         layout = self.layout
1468
1469         layout.operator("clip.track_copy_color", icon='COPY_ID')
1470
1471
1472 class CLIP_MT_stabilize_2d_specials(Menu):
1473     bl_label = "Translation Track Specials"
1474
1475     def draw(self, context):
1476         layout = self.layout
1477
1478         layout.operator("clip.stabilize_2d_select")
1479
1480
1481 class CLIP_MT_stabilize_2d_rotation_specials(Menu):
1482     bl_label = "Rotation Track Specials"
1483
1484     def draw(self, context):
1485         layout = self.layout
1486
1487         layout.operator("clip.stabilize_2d_rotation_select")
1488
1489
1490 classes = (
1491     CLIP_UL_tracking_objects,
1492     CLIP_HT_header,
1493     CLIP_MT_track,
1494     CLIP_MT_tracking_editor_menus,
1495     CLIP_MT_masking_editor_menus,
1496     CLIP_PT_track,
1497     CLIP_PT_tools_clip,
1498     CLIP_PT_tools_marker,
1499     CLIP_PT_tracking_settings,
1500     CLIP_PT_tools_tracking,
1501     CLIP_PT_tools_plane_tracking,
1502     CLIP_PT_tools_solve,
1503     CLIP_PT_tools_cleanup,
1504     CLIP_PT_tools_geometry,
1505     CLIP_PT_tools_orientation,
1506     CLIP_PT_tools_object,
1507     CLIP_PT_objects,
1508     CLIP_PT_plane_track,
1509     CLIP_PT_track_settings,
1510     CLIP_PT_tracking_camera,
1511     CLIP_PT_tracking_lens,
1512     CLIP_PT_display,
1513     CLIP_PT_marker,
1514     CLIP_PT_marker_display,
1515     CLIP_PT_stabilization,
1516     CLIP_PT_proxy,
1517     CLIP_PT_mask,
1518     CLIP_PT_mask_layers,
1519     CLIP_PT_mask_display,
1520     CLIP_PT_active_mask_spline,
1521     CLIP_PT_active_mask_point,
1522     CLIP_PT_tools_mask,
1523     CLIP_PT_tools_mask_add,
1524     CLIP_PT_tools_mask_transforms,
1525     CLIP_PT_footage,
1526     CLIP_PT_footage_info,
1527     CLIP_PT_tools_scenesetup,
1528     CLIP_PT_grease_pencil,
1529     CLIP_PT_grease_pencil_palettecolor,
1530     CLIP_PT_tools_grease_pencil_draw,
1531     CLIP_PT_tools_grease_pencil_edit,
1532     CLIP_PT_tools_grease_pencil_sculpt,
1533     CLIP_PT_tools_grease_pencil_brush,
1534     CLIP_PT_tools_grease_pencil_brushcurves,
1535     CLIP_MT_view,
1536     CLIP_MT_clip,
1537     CLIP_MT_proxy,
1538     CLIP_MT_reconstruction,
1539     CLIP_MT_track_visibility,
1540     CLIP_MT_track_transform,
1541     CLIP_MT_select,
1542     CLIP_MT_select_grouped,
1543     CLIP_MT_tracking_specials,
1544     CLIP_MT_camera_presets,
1545     CLIP_MT_track_color_presets,
1546     CLIP_MT_tracking_settings_presets,
1547     CLIP_MT_track_color_specials,
1548     CLIP_MT_stabilize_2d_specials,
1549     CLIP_MT_stabilize_2d_rotation_specials,
1550 )
1551
1552 if __name__ == "__main__":  # only for live edit.
1553     from bpy.utils import register_class
1554     for cls in classes:
1555         register_class(cls)