1 # ##### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17 # ##### END GPL LICENSE BLOCK #####
21 # panels get subclassed (not registered directly)
22 # menus are referenced `as is`
25 from bpy.types import Menu, UIList
28 class MASK_UL_layers(UIList):
29 def draw_item(self, context, layout, data, item, icon,
30 active_data, active_propname, index):
31 # assert(isinstance(item, bpy.types.MaskLayer)
33 if self.layout_type in {'DEFAULT', 'COMPACT'}:
34 layout.prop(mask, "name", text="", emboss=False, icon_value=icon)
35 row = layout.row(align=True)
36 row.prop(mask, "hide", text="", emboss=False)
37 row.prop(mask, "hide_select", text="", emboss=False)
38 row.prop(mask, "hide_render", text="", emboss=False)
39 elif self.layout_type in {'GRID'}:
40 layout.alignment = 'CENTER'
41 layout.label(text="", icon_value=icon)
45 # subclasses must define...
46 #~ bl_space_type = 'CLIP_EDITOR'
47 #~ bl_region_type = 'UI'
48 bl_label = "Mask Settings"
49 bl_options = {'DEFAULT_CLOSED'}
52 def poll(cls, context):
53 space_data = context.space_data
54 return space_data.mask and space_data.mode == 'MASK'
56 def draw(self, context):
59 sc = context.space_data
62 col = layout.column(align=True)
63 col.prop(mask, "frame_start")
64 col.prop(mask, "frame_end")
68 # subclasses must define...
69 #~ bl_space_type = 'CLIP_EDITOR'
70 #~ bl_region_type = 'UI'
71 bl_label = "Mask Layers"
74 def poll(cls, context):
75 space_data = context.space_data
76 return space_data.mask and space_data.mode == 'MASK'
78 def draw(self, context):
81 sc = context.space_data
83 active_layer = mask.layers.active
85 rows = 4 if active_layer else 1
88 row.template_list("MASK_UL_layers", "", mask, "layers",
89 mask, "active_layer_index", rows=rows)
91 sub = row.column(align=True)
93 sub.operator("mask.layer_new", icon='ZOOMIN', text="")
94 sub.operator("mask.layer_remove", icon='ZOOMOUT', text="")
99 sub.operator("mask.layer_move", icon='TRIA_UP', text="").direction = 'UP'
100 sub.operator("mask.layer_move", icon='TRIA_DOWN', text="").direction = 'DOWN'
103 row = layout.row(align=True)
104 row.prop(active_layer, "alpha")
105 row.prop(active_layer, "invert", text="", icon='IMAGE_ALPHA')
107 layout.prop(active_layer, "blend")
108 layout.prop(active_layer, "falloff")
110 row = layout.row(align=True)
111 row.prop(active_layer, "use_fill_overlap", text="Overlap")
112 row.prop(active_layer, "use_fill_holes", text="Holes")
115 class MASK_PT_spline():
116 # subclasses must define...
117 #~ bl_space_type = 'CLIP_EDITOR'
118 #~ bl_region_type = 'UI'
119 bl_label = "Active Spline"
122 def poll(cls, context):
123 sc = context.space_data
126 if mask and sc.mode == 'MASK':
127 return mask.layers.active and mask.layers.active.splines.active
131 def draw(self, context):
134 sc = context.space_data
136 spline = mask.layers.active.splines.active
138 col = layout.column()
139 col.prop(spline, "offset_mode")
140 col.prop(spline, "weight_interpolation")
143 row.prop(spline, "use_cyclic")
144 row.prop(spline, "use_fill")
146 col.prop(spline, "use_self_intersection_check")
149 class MASK_PT_point():
150 # subclasses must define...
151 #~ bl_space_type = 'CLIP_EDITOR'
152 #~ bl_region_type = 'UI'
153 bl_label = "Active Point"
156 def poll(cls, context):
157 sc = context.space_data
160 if mask and sc.mode == 'MASK':
161 mask_layer_active = mask.layers.active
162 return (mask_layer_active and
163 mask_layer_active.splines.active_point)
167 def draw(self, context):
170 sc = context.space_data
172 point = mask.layers.active.splines.active_point
173 parent = point.parent
175 col = layout.column()
176 # Currently only parenting yo movie clip is allowed, so do not
177 # ver-oplicate things for now and use single template_ID
178 #col.template_any_ID(parent, "id", "id_type", text="")
181 col.prop(parent, "id", text="")
183 if parent.id_type == 'MOVIECLIP' and parent.id:
185 tracking = clip.tracking
188 row.prop(parent, "type", expand=True)
190 col.prop_search(parent, "parent", tracking,
191 "objects", icon='OBJECT_DATA', text="Object:")
193 tracks_list = "tracks" if parent.type == 'POINT_TRACK' else 'plane_tracks'
195 if parent.parent in tracking.objects:
196 object = tracking.objects[parent.parent]
197 col.prop_search(parent, "sub_parent", object,
198 tracks_list, icon='ANIM_DATA', text="Track:")
200 col.prop_search(parent, "sub_parent", tracking,
201 tracks_list, icon='ANIM_DATA', text="Track:")
204 class MASK_PT_display():
205 # subclasses must define...
206 #~ bl_space_type = 'CLIP_EDITOR'
207 #~ bl_region_type = 'UI'
208 bl_label = "Mask Display"
209 bl_options = {'DEFAULT_CLOSED'}
212 def poll(cls, context):
213 space_data = context.space_data
214 return space_data.mask and space_data.mode == 'MASK'
216 def draw(self, context):
219 space_data = context.space_data
220 row = layout.row(align=True)
221 row.prop(space_data, "show_mask_smooth", text="Smooth")
222 row.prop(space_data, "mask_draw_type", text="")
223 row = layout.row(align=True)
224 row.prop(space_data, "show_mask_overlay", text="Overlay")
226 sub.active = space_data.show_mask_overlay
227 sub.prop(space_data, "mask_overlay_mode", text="")
230 class MASK_PT_transforms():
231 # subclasses must define...
232 #~ bl_space_type = 'CLIP_EDITOR'
233 #~ bl_region_type = 'TOOLS'
234 bl_label = "Transforms"
236 bl_options = {'DEFAULT_CLOSED'}
239 def poll(cls, context):
240 space_data = context.space_data
241 return space_data.mask and space_data.mode == 'MASK'
243 def draw(self, context):
246 col = layout.column(align=True)
247 col.label(text="Transform:")
248 col.operator("transform.translate")
249 col.operator("transform.rotate")
250 col.operator("transform.resize", text="Scale")
251 col.operator("transform.transform", text="Scale Feather").mode = 'MASK_SHRINKFATTEN'
254 class MASK_PT_tools():
255 # subclasses must define...
256 #~ bl_space_type = 'CLIP_EDITOR'
257 #~ bl_region_type = 'TOOLS'
258 bl_label = "Mask Tools"
262 def poll(cls, context):
263 space_data = context.space_data
264 return space_data.mask and space_data.mode == 'MASK'
266 def draw(self, context):
269 col = layout.column(align=True)
270 col.label(text="Spline:")
271 col.operator("mask.delete")
272 col.operator("mask.cyclic_toggle")
273 col.operator("mask.switch_direction")
274 col.operator("mask.handle_type_set")
275 col.operator("mask.feather_weight_clear")
277 col = layout.column(align=True)
278 col.label(text="Parenting:")
279 row = col.row(align=True)
280 row.operator("mask.parent_set", text="Parent")
281 row.operator("mask.parent_clear", text="Clear")
283 col = layout.column(align=True)
284 col.label(text="Animation:")
285 row = col.row(align=True)
286 row.operator("mask.shape_key_insert", text="Insert Key")
287 row.operator("mask.shape_key_clear", text="Clear Key")
288 col.operator("mask.shape_key_feather_reset", text="Reset Feather Animation")
289 col.operator("mask.shape_key_rekey", text="Re-Key Shape Points")
293 # subclasses must define...
294 #~ bl_space_type = 'CLIP_EDITOR'
295 #~ bl_region_type = 'TOOLS'
300 def poll(cls, context):
301 space_data = context.space_data
302 return space_data.mode == 'MASK'
304 def draw(self, context):
307 col = layout.column(align=True)
308 col.operator("mask.primitive_circle_add", icon='MESH_CIRCLE')
309 col.operator("mask.primitive_square_add", icon='MESH_PLANE')
312 class MASK_MT_mask(Menu):
315 def draw(self, context):
318 layout.operator("mask.delete")
321 layout.operator("mask.cyclic_toggle")
322 layout.operator("mask.switch_direction")
323 layout.operator("mask.normals_make_consistent")
324 layout.operator("mask.feather_weight_clear") # TODO, better place?
327 layout.operator("mask.parent_clear")
328 layout.operator("mask.parent_set")
331 layout.operator("mask.copy_splines")
332 layout.operator("mask.paste_splines")
335 layout.menu("MASK_MT_visibility")
336 layout.menu("MASK_MT_transform")
337 layout.menu("MASK_MT_animation")
340 class MASK_MT_visibility(Menu):
341 bl_label = "Show/Hide"
343 def draw(self, context):
346 layout.operator("mask.hide_view_clear", text="Show Hidden")
347 layout.operator("mask.hide_view_set", text="Hide Selected")
348 layout.operator("mask.hide_view_set", text="Hide Unselected").unselected = True
351 class MASK_MT_transform(Menu):
352 bl_label = "Transform"
354 def draw(self, context):
357 layout.operator("transform.translate")
358 layout.operator("transform.rotate")
359 layout.operator("transform.resize")
360 layout.operator("transform.transform", text="Scale Feather").mode = 'MASK_SHRINKFATTEN'
363 class MASK_MT_animation(Menu):
364 bl_label = "Animation"
366 def draw(self, context):
369 layout.operator("mask.shape_key_clear")
370 layout.operator("mask.shape_key_insert")
371 layout.operator("mask.shape_key_feather_reset")
372 layout.operator("mask.shape_key_rekey")
375 class MASK_MT_select(Menu):
378 def draw(self, context):
380 sc = context.space_data
382 layout.operator("mask.select_border")
383 layout.operator("mask.select_circle")
387 layout.operator("mask.select_more")
388 layout.operator("mask.select_less")
392 layout.operator("mask.select_all").action = 'TOGGLE'
393 layout.operator("mask.select_all", text="Inverse").action = 'INVERT'
394 layout.operator("mask.select_linked", text="Select Linked")
396 if __name__ == "__main__": # only for live edit.
397 bpy.utils.register_module(__name__)