This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/release/scripts/startup/bl_ui/properties_mask_common.py
Sergey Sharybin c1ffea157c Mask editor: Always use smooth drawing
The mask is expected to be always be displayed smooth, and the
option mainly existed for some legacy drivers. IF smooth drawing
causes issues it should be fixed in the drawing code, not as an
option in the interface.

Differential Revision: https://developer.blender.org/D15266
2022-06-28 10:55:45 +02:00

434 lines
13 KiB
Python

# SPDX-License-Identifier: GPL-2.0-or-later
# panels get subclassed (not registered directly)
# menus are referenced `as is`
from bpy.types import Menu, UIList
from bpy.app.translations import contexts as i18n_contexts
# Use by both image & clip context menus.
def draw_mask_context_menu(layout, _context):
layout.operator_menu_enum("mask.handle_type_set", "type")
layout.operator("mask.switch_direction")
layout.operator("mask.cyclic_toggle")
layout.separator()
layout.operator("mask.copy_splines", icon='COPYDOWN')
layout.operator("mask.paste_splines", icon='PASTEDOWN')
layout.separator()
layout.operator("mask.shape_key_rekey", text="Re-Key Shape Points")
layout.operator("mask.feather_weight_clear")
layout.operator("mask.shape_key_feather_reset", text="Reset Feather Animation")
layout.separator()
layout.operator("mask.parent_set")
layout.operator("mask.parent_clear")
layout.separator()
layout.operator("mask.delete")
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 = 'HEADER'
bl_label = "Mask Display"
@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_spline", text="Spline")
sub = row.row()
sub.active = space_data.show_mask_spline
sub.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="")
row = layout.row()
row.active = (space_data.mask_overlay_mode in ['COMBINED'] and space_data.show_mask_overlay)
row.prop(space_data, "blend_factor", text="Blending Factor")
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.menu("MASK_MT_transform")
layout.operator("mask.feather_weight_clear")
layout.separator()
layout.operator("mask.cyclic_toggle")
layout.operator("mask.handle_type_set")
layout.operator("mask.normals_make_consistent")
layout.operator("mask.switch_direction")
layout.separator()
layout.operator("mask.copy_splines")
layout.operator("mask.paste_splines")
layout.separator()
layout.operator("mask.parent_clear")
layout.operator("mask.parent_set")
layout.separator()
layout.menu("MASK_MT_animation")
layout.separator()
layout.menu("MASK_MT_visibility")
layout.operator("mask.delete")
class MASK_MT_add(Menu):
bl_idname = "MASK_MT_add"
bl_label = "Add"
bl_translation_context = i18n_contexts.operator_default
def draw(self, _context):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
layout.operator("mask.primitive_circle_add", text="Circle", icon='MESH_CIRCLE')
layout.operator("mask.primitive_square_add", text="Square", icon='MESH_PLANE')
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.separator()
layout.operator("transform.tosphere")
layout.operator("transform.shear")
layout.operator("transform.push_pull")
layout.separator()
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.operator_menu_enum("mask.select_lasso", "mode")
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_add,
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)