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