123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396 |
- # ##### BEGIN GPL LICENSE BLOCK #####
- #
- # This program is free software; you can redistribute it and/or
- # modify it under the terms of the GNU General Public License
- # as published by the Free Software Foundation; either version 2
- # of the License, or (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software Foundation,
- # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- #
- # ##### END GPL LICENSE BLOCK #####
- # <pep8-80 compliant>
- # panels get subclassed (not registered directly)
- # menus are referenced `as is`
- from bpy.types import Menu, UIList
- class MASK_UL_layers(UIList):
- def draw_item(self, _context, layout, _data, item, icon,
- _active_data, _active_propname, _index):
- # assert(isinstance(item, bpy.types.MaskLayer)
- mask = item
- if self.layout_type in {'DEFAULT', 'COMPACT'}:
- layout.prop(mask, "name", text="", emboss=False, icon_value=icon)
- row = layout.row(align=True)
- row.prop(mask, "hide", text="", emboss=False)
- row.prop(mask, "hide_select", text="", emboss=False)
- row.prop(mask, "hide_render", text="", emboss=False)
- elif self.layout_type == 'GRID':
- layout.alignment = 'CENTER'
- layout.label(text="", icon_value=icon)
- class MASK_PT_mask:
- # subclasses must define...
- # ~ bl_space_type = 'CLIP_EDITOR'
- # ~ bl_region_type = 'UI'
- bl_label = "Mask Settings"
- bl_options = {'DEFAULT_CLOSED'}
- @classmethod
- def poll(cls, context):
- space_data = context.space_data
- return space_data.mask and space_data.mode == 'MASK'
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
- sc = context.space_data
- mask = sc.mask
- col = layout.column(align=True)
- col.prop(mask, "frame_start")
- col.prop(mask, "frame_end")
- class MASK_PT_layers:
- # subclasses must define...
- # ~ bl_space_type = 'CLIP_EDITOR'
- # ~ bl_region_type = 'UI'
- bl_label = "Mask Layers"
- @classmethod
- def poll(cls, context):
- space_data = context.space_data
- return space_data.mask and space_data.mode == 'MASK'
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
- sc = context.space_data
- mask = sc.mask
- active_layer = mask.layers.active
- rows = 4 if active_layer else 1
- row = layout.row()
- row.template_list("MASK_UL_layers", "", mask, "layers",
- mask, "active_layer_index", rows=rows)
- sub = row.column(align=True)
- sub.operator("mask.layer_new", icon='ADD', text="")
- sub.operator("mask.layer_remove", icon='REMOVE', text="")
- if active_layer:
- sub.separator()
- sub.operator("mask.layer_move", icon='TRIA_UP', text="").direction = 'UP'
- sub.operator("mask.layer_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
- # blending
- row = layout.row(align=True)
- row.prop(active_layer, "alpha")
- row.prop(active_layer, "invert", text="", icon='IMAGE_ALPHA')
- layout.prop(active_layer, "blend")
- layout.prop(active_layer, "falloff")
- col = layout.column()
- col.prop(active_layer, "use_fill_overlap", text="Overlap")
- col.prop(active_layer, "use_fill_holes", text="Holes")
- class MASK_PT_spline:
- # subclasses must define...
- # ~ bl_space_type = 'CLIP_EDITOR'
- # ~ bl_region_type = 'UI'
- bl_label = "Active Spline"
- @classmethod
- def poll(cls, context):
- sc = context.space_data
- mask = sc.mask
- if mask and sc.mode == 'MASK':
- return mask.layers.active and mask.layers.active.splines.active
- return False
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
- sc = context.space_data
- mask = sc.mask
- spline = mask.layers.active.splines.active
- col = layout.column()
- col.prop(spline, "offset_mode")
- col.prop(spline, "weight_interpolation", text="Interpolation")
- col.prop(spline, "use_cyclic")
- col.prop(spline, "use_fill")
- col.prop(spline, "use_self_intersection_check")
- class MASK_PT_point:
- # subclasses must define...
- # ~ bl_space_type = 'CLIP_EDITOR'
- # ~ bl_region_type = 'UI'
- bl_label = "Active Point"
- @classmethod
- def poll(cls, context):
- sc = context.space_data
- mask = sc.mask
- if mask and sc.mode == 'MASK':
- mask_layer_active = mask.layers.active
- return (mask_layer_active and
- mask_layer_active.splines.active_point)
- return False
- def draw(self, context):
- layout = self.layout
- layout.use_property_split = True
- layout.use_property_decorate = False
- sc = context.space_data
- mask = sc.mask
- point = mask.layers.active.splines.active_point
- parent = point.parent
- col = layout.column()
- # Currently only parenting the movie-clip is allowed,
- # so do not over-complicate things for now by using single template_ID
- #col.template_any_ID(parent, "id", "id_type", text="")
- col.label(text="Parent:")
- col.prop(parent, "id", text="")
- if parent.id_type == 'MOVIECLIP' and parent.id:
- clip = parent.id
- tracking = clip.tracking
- row = col.row()
- row.prop(parent, "type", expand=True)
- col.prop_search(parent, "parent", tracking,
- "objects", icon='OBJECT_DATA', text="Object")
- tracks_list = "tracks" if parent.type == 'POINT_TRACK' else "plane_tracks"
- if parent.parent in tracking.objects:
- ob = tracking.objects[parent.parent]
- col.prop_search(parent, "sub_parent", ob,
- tracks_list, icon='ANIM_DATA', text="Track")
- else:
- col.prop_search(parent, "sub_parent", tracking,
- tracks_list, icon='ANIM_DATA', text="Track")
- class MASK_PT_display:
- # subclasses must define...
- # ~ bl_space_type = 'CLIP_EDITOR'
- # ~ bl_region_type = 'UI'
- bl_label = "Mask Display"
- bl_options = {'DEFAULT_CLOSED'}
- @classmethod
- def poll(cls, context):
- space_data = context.space_data
- return space_data.mask and space_data.mode == 'MASK'
- def draw(self, context):
- layout = self.layout
- space_data = context.space_data
- row = layout.row(align=True)
- row.prop(space_data, "show_mask_smooth", text="Smooth")
- row.prop(space_data, "mask_display_type", text="")
- row = layout.row(align=True)
- row.prop(space_data, "show_mask_overlay", text="Overlay")
- sub = row.row()
- sub.active = space_data.show_mask_overlay
- sub.prop(space_data, "mask_overlay_mode", text="")
- class MASK_PT_transforms:
- # subclasses must define...
- # ~ bl_space_type = 'CLIP_EDITOR'
- # ~ bl_region_type = 'TOOLS'
- bl_label = "Transforms"
- bl_category = "Mask"
- @classmethod
- def poll(cls, context):
- space_data = context.space_data
- return space_data.mask and space_data.mode == 'MASK'
- def draw(self, _context):
- layout = self.layout
- col = layout.column(align=True)
- col.label(text="Transform:")
- col.operator("transform.translate")
- col.operator("transform.rotate")
- col.operator("transform.resize", text="Scale")
- col.operator("transform.transform", text="Scale Feather").mode = 'MASK_SHRINKFATTEN'
- class MASK_PT_tools:
- bl_label = "Mask Tools"
- bl_category = "Mask"
- @classmethod
- def poll(cls, context):
- space_data = context.space_data
- return space_data.mask and space_data.mode == 'MASK'
- def draw(self, _context):
- layout = self.layout
- col = layout.column(align=True)
- col.label(text="Spline:")
- col.operator("mask.delete")
- col.operator("mask.cyclic_toggle")
- col.operator("mask.switch_direction")
- col.operator("mask.handle_type_set").type = 'VECTOR'
- col.operator("mask.feather_weight_clear")
- col = layout.column(align=True)
- col.label(text="Parenting:")
- row = col.row(align=True)
- row.operator("mask.parent_set", text="Parent")
- row.operator("mask.parent_clear", text="Clear")
- col = layout.column(align=True)
- col.label(text="Animation:")
- row = col.row(align=True)
- row.operator("mask.shape_key_insert", text="Insert Key")
- row.operator("mask.shape_key_clear", text="Clear Key")
- col.operator("mask.shape_key_feather_reset", text="Reset Feather Animation")
- col.operator("mask.shape_key_rekey", text="Re-Key Shape Points")
- class MASK_MT_mask(Menu):
- bl_label = "Mask"
- def draw(self, _context):
- layout = self.layout
- layout.operator("mask.delete")
- layout.separator()
- layout.operator("mask.cyclic_toggle")
- layout.operator("mask.switch_direction")
- layout.operator("mask.normals_make_consistent")
- layout.operator("mask.handle_type_set")
- layout.operator("mask.feather_weight_clear") # TODO, better place?
- layout.separator()
- layout.operator("mask.parent_clear")
- layout.operator("mask.parent_set")
- layout.separator()
- layout.operator("mask.copy_splines")
- layout.operator("mask.paste_splines")
- layout.separator()
- layout.menu("MASK_MT_visibility")
- layout.menu("MASK_MT_transform")
- layout.menu("MASK_MT_animation")
- class MASK_MT_visibility(Menu):
- bl_label = "Show/Hide"
- def draw(self, _context):
- layout = self.layout
- layout.operator("mask.hide_view_clear")
- layout.operator("mask.hide_view_set", text="Hide Selected").unselected = False
- layout.operator("mask.hide_view_set", text="Hide Unselected").unselected = True
- class MASK_MT_transform(Menu):
- bl_label = "Transform"
- def draw(self, _context):
- layout = self.layout
- layout.operator("transform.translate")
- layout.operator("transform.rotate")
- layout.operator("transform.resize")
- layout.operator("transform.transform", text="Scale Feather").mode = 'MASK_SHRINKFATTEN'
- class MASK_MT_animation(Menu):
- bl_label = "Animation"
- def draw(self, _context):
- layout = self.layout
- layout.operator("mask.shape_key_clear")
- layout.operator("mask.shape_key_insert")
- layout.operator("mask.shape_key_feather_reset")
- layout.operator("mask.shape_key_rekey")
- class MASK_MT_select(Menu):
- bl_label = "Select"
- def draw(self, _context):
- layout = self.layout
- layout.operator("mask.select_all", text="All").action = 'SELECT'
- layout.operator("mask.select_all", text="None").action = 'DESELECT'
- layout.operator("mask.select_all", text="Invert").action = 'INVERT'
- layout.separator()
- layout.operator("mask.select_box")
- layout.operator("mask.select_circle")
- layout.separator()
- layout.operator("mask.select_more")
- layout.operator("mask.select_less")
- layout.separator()
- layout.operator("mask.select_linked", text="Select Linked")
- classes = (
- MASK_UL_layers,
- MASK_MT_mask,
- MASK_MT_visibility,
- MASK_MT_transform,
- MASK_MT_animation,
- MASK_MT_select,
- )
- if __name__ == "__main__": # only for live edit.
- from bpy.utils import register_class
- for cls in classes:
- register_class(cls)
|