svn merge ^/trunk/blender -r49601:49620
[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
131 class MASK_PT_point():
132     # subclasses must define...
133     #~ bl_space_type = 'CLIP_EDITOR'
134     #~ bl_region_type = 'UI'
135     bl_label = "Active Point"
136
137     @classmethod
138     def poll(cls, context):
139         sc = context.space_data
140         mask = sc.mask
141
142         if mask and sc.mode == 'MASK':
143             mask_layer_active = mask.layers.active
144             return (mask_layer_active and
145                     mask_layer_active.splines.active_point)
146
147         return False
148
149     def draw(self, context):
150         layout = self.layout
151
152         sc = context.space_data
153         mask = sc.mask
154         point = mask.layers.active.splines.active_point
155         parent = point.parent
156
157         col = layout.column()
158         col.prop(point, "handle_type")
159
160         col = layout.column()
161         # Currently only parenting yo movie clip is allowed, so do not
162         # ver-oplicate things for now and use single template_ID
163         #col.template_any_ID(parent, "id", "id_type", text="")
164
165         col.label("Parent:")
166         col.prop(parent, "id", text="")
167
168         if parent.id_type == 'MOVIECLIP' and parent.id:
169             clip = parent.id
170             tracking = clip.tracking
171
172             col.prop_search(parent, "parent", tracking,
173                             "objects", icon='OBJECT_DATA', text="Object:")
174
175             if parent.parent in tracking.objects:
176                 object = tracking.objects[parent.parent]
177                 col.prop_search(parent, "sub_parent", object,
178                                 "tracks", icon='ANIM_DATA', text="Track:")
179             else:
180                 col.prop_search(parent, "sub_parent", tracking,
181                                 "tracks", icon='ANIM_DATA', text="Track:")
182
183
184 class MASK_PT_display():
185     # subclasses must define...
186     #~ bl_space_type = 'CLIP_EDITOR'
187     #~ bl_region_type = 'UI'
188     bl_label = "Mask Display"
189     bl_options = {'DEFAULT_CLOSED'}
190
191     @classmethod
192     def poll(cls, context):
193         space_data = context.space_data
194         return space_data.mask and space_data.mode == 'MASK'
195
196     def draw(self, context):
197         layout = self.layout
198
199         space_data = context.space_data
200
201         layout.prop(space_data, "mask_draw_type", text="")
202         layout.prop(space_data, "show_mask_smooth")
203
204
205 class MASK_PT_tools():
206     # subclasses must define...
207     #~ bl_space_type = 'CLIP_EDITOR'
208     #~ bl_region_type = 'TOOLS'
209     bl_label = "Mask Tools"
210
211     @classmethod
212     def poll(cls, context):
213         space_data = context.space_data
214         return space_data.mask and space_data.mode == 'MASK'
215
216     def draw(self, context):
217         layout = self.layout
218
219         col = layout.column(align=True)
220         col.label(text="Transform:")
221         col.operator("transform.translate")
222         col.operator("transform.rotate")
223         col.operator("transform.resize", text="Scale")
224         props = col.operator("transform.transform", text="Shrink/Fatten")
225         props.mode = 'MASK_SHRINKFATTEN'
226
227         col = layout.column(align=True)
228         col.label(text="Spline:")
229         col.operator("mask.delete")
230         col.operator("mask.cyclic_toggle")
231         col.operator("mask.switch_direction")
232
233         col = layout.column(align=True)
234         col.label(text="Parenting:")
235         col.operator("mask.parent_set")
236         col.operator("mask.parent_clear")
237
238
239 class MASK_MT_mask(Menu):
240     bl_label = "Mask"
241
242     def draw(self, context):
243         layout = self.layout
244
245         layout.operator("mask.delete")
246
247         layout.separator()
248         layout.operator("mask.cyclic_toggle")
249         layout.operator("mask.switch_direction")
250         layout.operator("mask.normals_make_consistent")
251         layout.operator("mask.feather_weight_clear")  # TODO, better place?
252
253         layout.separator()
254         layout.operator("mask.parent_clear")
255         layout.operator("mask.parent_set")
256
257         layout.separator()
258         layout.menu("MASK_MT_visibility")
259         layout.menu("MASK_MT_transform")
260         layout.menu("MASK_MT_animation")
261
262
263 class MASK_MT_visibility(Menu):
264     bl_label = "Show/Hide"
265
266     def draw(self, context):
267         layout = self.layout
268
269         layout.operator("mask.hide_view_clear", text="Show Hidden")
270         layout.operator("mask.hide_view_set", text="Hide Selected")
271
272         props = layout.operator("mask.hide_view_set", text="Hide Unselected")
273         props.unselected = True
274
275
276 class MASK_MT_transform(Menu):
277     bl_label = "Transform"
278
279     def draw(self, context):
280         layout = self.layout
281
282         layout.operator("transform.translate")
283         layout.operator("transform.rotate")
284         layout.operator("transform.resize")
285         props = layout.operator("transform.transform", text="Shrink/Fatten")
286         props.mode = 'MASK_SHRINKFATTEN'
287
288
289 class MASK_MT_animation(Menu):
290     bl_label = "Animation"
291
292     def draw(self, context):
293         layout = self.layout
294
295         layout.operator("mask.shape_key_clear")
296         layout.operator("mask.shape_key_insert")
297         layout.operator("mask.shape_key_feather_reset")
298         layout.operator("mask.shape_key_rekey")
299
300
301 class MASK_MT_select(Menu):
302     bl_label = "Select"
303
304     def draw(self, context):
305         layout = self.layout
306         sc = context.space_data
307
308         layout.operator("mask.select_border")
309         layout.operator("mask.select_circle")
310
311         layout.separator()
312
313         layout.operator("mask.select_all").action = 'TOGGLE'
314         layout.operator("mask.select_all", text="Inverse").action = 'INVERT'
315
316 if __name__ == "__main__":  # only for live edit.
317     bpy.utils.register_module(__name__)