add animation buttons to mask toolbar
[blender.git] / release / scripts / startup / bl_ui / properties_mask_common.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 # panels get subclassed (not registered directly)
22 # menus are referenced `as is`
23
24 import bpy
25 from bpy.types import Menu
26
27
28 class MASK_PT_mask:
29     # subclasses must define...
30     #~ bl_space_type = 'CLIP_EDITOR'
31     #~ bl_region_type = 'UI'
32     bl_label = "Mask Settings"
33     bl_options = {'DEFAULT_CLOSED'}
34
35     @classmethod
36     def poll(cls, context):
37         space_data = context.space_data
38         return space_data.mask and space_data.mode == 'MASK'
39
40     def draw(self, context):
41         layout = self.layout
42
43         sc = context.space_data
44         mask = sc.mask
45
46         col = layout.column(align=True)
47         col.prop(mask, "frame_start")
48         col.prop(mask, "frame_end")
49
50
51 class MASK_PT_layers:
52     # subclasses must define...
53     #~ bl_space_type = 'CLIP_EDITOR'
54     #~ bl_region_type = 'UI'
55     bl_label = "Mask Layers"
56
57     @classmethod
58     def poll(cls, context):
59         space_data = context.space_data
60         return space_data.mask and space_data.mode == 'MASK'
61
62     def draw(self, context):
63         layout = self.layout
64
65         sc = context.space_data
66         mask = sc.mask
67         active_layer = mask.layers.active
68
69         rows = 5 if active_layer else 2
70
71         row = layout.row()
72         row.template_list(mask, "layers",
73                           mask, "active_layer_index", rows=rows)
74
75         sub = row.column(align=True)
76
77         sub.operator("mask.layer_new", icon='ZOOMIN', text="")
78         sub.operator("mask.layer_remove", icon='ZOOMOUT', text="")
79
80         if active_layer:
81             sub.separator()
82
83             props = sub.operator("mask.layer_move", icon='TRIA_UP', text="")
84             props.direction = 'UP'
85
86             props = sub.operator("mask.layer_move", icon='TRIA_DOWN', text="")
87             props.direction = 'DOWN'
88
89             layout.prop(active_layer, "name")
90
91             # blending
92             row = layout.row(align=True)
93             row.prop(active_layer, "alpha")
94             row.prop(active_layer, "invert", text="", icon='IMAGE_ALPHA')
95
96             layout.prop(active_layer, "blend")
97             layout.prop(active_layer, "falloff")
98
99
100 class MASK_PT_spline():
101     # subclasses must define...
102     #~ bl_space_type = 'CLIP_EDITOR'
103     #~ bl_region_type = 'UI'
104     bl_label = "Active Spline"
105
106     @classmethod
107     def poll(cls, context):
108         sc = context.space_data
109         mask = sc.mask
110
111         if mask and sc.mode == 'MASK':
112             return mask.layers.active and mask.layers.active.splines.active
113
114         return False
115
116     def draw(self, context):
117         layout = self.layout
118
119         sc = context.space_data
120         mask = sc.mask
121         spline = mask.layers.active.splines.active
122
123         col = layout.column()
124         col.prop(spline, "weight_interpolation")
125
126         row = col.row()
127         row.prop(spline, "use_cyclic")
128         row.prop(spline, "use_fill")
129
130         col.prop(spline, "use_self_intersection_check")
131
132
133 class MASK_PT_point():
134     # subclasses must define...
135     #~ bl_space_type = 'CLIP_EDITOR'
136     #~ bl_region_type = 'UI'
137     bl_label = "Active Point"
138
139     @classmethod
140     def poll(cls, context):
141         sc = context.space_data
142         mask = sc.mask
143
144         if mask and sc.mode == 'MASK':
145             mask_layer_active = mask.layers.active
146             return (mask_layer_active and
147                     mask_layer_active.splines.active_point)
148
149         return False
150
151     def draw(self, context):
152         layout = self.layout
153
154         sc = context.space_data
155         mask = sc.mask
156         point = mask.layers.active.splines.active_point
157         parent = point.parent
158
159         col = layout.column()
160         col.prop(point, "handle_type")
161
162         col = layout.column()
163         # Currently only parenting yo movie clip is allowed, so do not
164         # ver-oplicate things for now and use single template_ID
165         #col.template_any_ID(parent, "id", "id_type", text="")
166
167         col.label("Parent:")
168         col.prop(parent, "id", text="")
169
170         if parent.id_type == 'MOVIECLIP' and parent.id:
171             clip = parent.id
172             tracking = clip.tracking
173
174             col.prop_search(parent, "parent", tracking,
175                             "objects", icon='OBJECT_DATA', text="Object:")
176
177             if parent.parent in tracking.objects:
178                 object = tracking.objects[parent.parent]
179                 col.prop_search(parent, "sub_parent", object,
180                                 "tracks", icon='ANIM_DATA', text="Track:")
181             else:
182                 col.prop_search(parent, "sub_parent", tracking,
183                                 "tracks", icon='ANIM_DATA', text="Track:")
184
185
186 class MASK_PT_display():
187     # subclasses must define...
188     #~ bl_space_type = 'CLIP_EDITOR'
189     #~ bl_region_type = 'UI'
190     bl_label = "Mask Display"
191     bl_options = {'DEFAULT_CLOSED'}
192
193     @classmethod
194     def poll(cls, context):
195         space_data = context.space_data
196         return space_data.mask and space_data.mode == 'MASK'
197
198     def draw(self, context):
199         layout = self.layout
200
201         space_data = context.space_data
202
203         layout.prop(space_data, "mask_draw_type", text="")
204         layout.prop(space_data, "show_mask_smooth")
205
206
207 class MASK_PT_tools():
208     # subclasses must define...
209     #~ bl_space_type = 'CLIP_EDITOR'
210     #~ bl_region_type = 'TOOLS'
211     bl_label = "Mask Tools"
212
213     @classmethod
214     def poll(cls, context):
215         space_data = context.space_data
216         return space_data.mask and space_data.mode == 'MASK'
217
218     def draw(self, context):
219         layout = self.layout
220
221         col = layout.column(align=True)
222         col.label(text="Transform:")
223         col.operator("transform.translate")
224         col.operator("transform.rotate")
225         col.operator("transform.resize", text="Scale")
226         props = col.operator("transform.transform", text="Shrink/Fatten")
227         props.mode = 'MASK_SHRINKFATTEN'
228
229         col = layout.column(align=True)
230         col.label(text="Spline:")
231         col.operator("mask.delete")
232         col.operator("mask.cyclic_toggle")
233         col.operator("mask.switch_direction")
234
235         col = layout.column(align=True)
236         col.label(text="Parenting:")
237         col.operator("mask.parent_set")
238         col.operator("mask.parent_clear")
239
240         col = layout.column(align=True)
241         col.label(text="Animation:")
242         col.operator("mask.shape_key_clear")
243         col.operator("mask.shape_key_insert")
244         col.operator("mask.shape_key_feather_reset")
245         col.operator("mask.shape_key_rekey")
246
247
248 class MASK_MT_mask(Menu):
249     bl_label = "Mask"
250
251     def draw(self, context):
252         layout = self.layout
253
254         layout.operator("mask.delete")
255
256         layout.separator()
257         layout.operator("mask.cyclic_toggle")
258         layout.operator("mask.switch_direction")
259         layout.operator("mask.normals_make_consistent")
260         layout.operator("mask.feather_weight_clear")  # TODO, better place?
261
262         layout.separator()
263         layout.operator("mask.parent_clear")
264         layout.operator("mask.parent_set")
265
266         layout.separator()
267         layout.menu("MASK_MT_visibility")
268         layout.menu("MASK_MT_transform")
269         layout.menu("MASK_MT_animation")
270
271
272 class MASK_MT_visibility(Menu):
273     bl_label = "Show/Hide"
274
275     def draw(self, context):
276         layout = self.layout
277
278         layout.operator("mask.hide_view_clear", text="Show Hidden")
279         layout.operator("mask.hide_view_set", text="Hide Selected")
280
281         props = layout.operator("mask.hide_view_set", text="Hide Unselected")
282         props.unselected = True
283
284
285 class MASK_MT_transform(Menu):
286     bl_label = "Transform"
287
288     def draw(self, context):
289         layout = self.layout
290
291         layout.operator("transform.translate")
292         layout.operator("transform.rotate")
293         layout.operator("transform.resize")
294         props = layout.operator("transform.transform", text="Shrink/Fatten")
295         props.mode = 'MASK_SHRINKFATTEN'
296
297
298 class MASK_MT_animation(Menu):
299     bl_label = "Animation"
300
301     def draw(self, context):
302         layout = self.layout
303
304         layout.operator("mask.shape_key_clear")
305         layout.operator("mask.shape_key_insert")
306         layout.operator("mask.shape_key_feather_reset")
307         layout.operator("mask.shape_key_rekey")
308
309
310 class MASK_MT_select(Menu):
311     bl_label = "Select"
312
313     def draw(self, context):
314         layout = self.layout
315         sc = context.space_data
316
317         layout.operator("mask.select_border")
318         layout.operator("mask.select_circle")
319
320         layout.separator()
321
322         layout.operator("mask.select_all").action = 'TOGGLE'
323         layout.operator("mask.select_all", text="Inverse").action = 'INVERT'
324
325 if __name__ == "__main__":  # only for live edit.
326     bpy.utils.register_module(__name__)