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