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