more ui api changes.
[blender.git] / release / scripts / ui / space_image.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., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
16 #
17 # ##### END GPL LICENSE BLOCK #####
18
19 # <pep8 compliant>
20 import bpy
21
22 narrowui = 180
23
24
25 class IMAGE_MT_view(bpy.types.Menu):
26     bl_label = "View"
27
28     def draw(self, context):
29         layout = self.layout
30
31         sima = context.space_data
32         # uv = sima.uv_editor
33         settings = context.tool_settings
34
35         show_uvedit = sima.show_uvedit
36
37         layout.operator("image.properties", icon='ICON_MENU_PANEL')
38
39         layout.separator()
40
41         layout.prop(sima, "update_automatically")
42         if show_uvedit:
43             layout.prop(settings, "uv_local_view") # Numpad /
44
45         layout.separator()
46
47         layout.operator("image.view_zoom_in")
48         layout.operator("image.view_zoom_out")
49
50         layout.separator()
51
52         ratios = [[1, 8], [1, 4], [1, 2], [1, 1], [2, 1], [4, 1], [8, 1]]
53
54         for a, b in ratios:
55             text = "Zoom %d:%d" % (a, b)
56             layout.operator("image.view_zoom_ratio", text=text).ratio = a / b
57
58         layout.separator()
59
60         if show_uvedit:
61             layout.operator("image.view_selected")
62
63         layout.operator("image.view_all")
64         layout.operator("screen.screen_full_area")
65
66
67 class IMAGE_MT_select(bpy.types.Menu):
68     bl_label = "Select"
69
70     def draw(self, context):
71         layout = self.layout
72
73         layout.operator("uv.select_border")
74         layout.operator("uv.select_border").pinned = True
75
76         layout.separator()
77
78         layout.operator("uv.select_all_toggle")
79         layout.operator("uv.select_inverse")
80         layout.operator("uv.unlink_selection")
81
82         layout.separator()
83
84         layout.operator("uv.select_pinned")
85         layout.operator("uv.select_linked")
86
87
88 class IMAGE_MT_image(bpy.types.Menu):
89     bl_label = "Image"
90
91     def draw(self, context):
92         layout = self.layout
93
94         sima = context.space_data
95         ima = sima.image
96
97         layout.operator("image.new")
98         layout.operator("image.open")
99
100         show_render = sima.show_render
101
102         if ima:
103             if not show_render:
104                 layout.operator("image.replace")
105                 layout.operator("image.reload")
106
107             layout.operator("image.save")
108             layout.operator("image.save_as")
109
110             if ima.source == 'SEQUENCE':
111                 layout.operator("image.save_sequence")
112
113             if not show_render:
114                 layout.separator()
115
116                 if ima.packed_file:
117                     layout.operator("image.unpack")
118                 else:
119                     layout.operator("image.pack")
120
121                 # only for dirty && specific image types, perhaps
122                 # this could be done in operator poll too
123                 if ima.dirty:
124                     if ima.source in ('FILE', 'GENERATED') and ima.type != 'MULTILAYER':
125                         layout.operator("image.pack", text="Pack As PNG").as_png = True
126
127             layout.separator()
128
129             layout.prop(sima, "image_painting")
130
131
132 class IMAGE_MT_uvs_showhide(bpy.types.Menu):
133     bl_label = "Show/Hide Faces"
134
135     def draw(self, context):
136         layout = self.layout
137
138         layout.operator("uv.reveal")
139         layout.operator("uv.hide")
140         layout.operator("uv.hide").unselected = True
141
142
143 class IMAGE_MT_uvs_transform(bpy.types.Menu):
144     bl_label = "Transform"
145
146     def draw(self, context):
147         layout = self.layout
148
149         layout.operator("tfm.translate")
150         layout.operator("tfm.rotate")
151         layout.operator("tfm.resize")
152
153
154 class IMAGE_MT_uvs_mirror(bpy.types.Menu):
155     bl_label = "Mirror"
156
157     def draw(self, context):
158         layout = self.layout
159         layout.operator_context = 'EXEC_REGION_WIN'
160
161         layout.operator("tfm.mirror", text="X Axis").constraint_axis[0] = True
162         layout.operator("tfm.mirror", text="Y Axis").constraint_axis[1] = True
163
164
165 class IMAGE_MT_uvs_weldalign(bpy.types.Menu):
166     bl_label = "Weld/Align"
167
168     def draw(self, context):
169         layout = self.layout
170
171         layout.operator("uv.weld") # W, 1
172         layout.operator_enums("uv.align", "axis") # W, 2/3/4
173
174
175 class IMAGE_MT_uvs(bpy.types.Menu):
176     bl_label = "UVs"
177
178     def draw(self, context):
179         layout = self.layout
180
181         sima = context.space_data
182         uv = sima.uv_editor
183         settings = context.tool_settings
184
185         layout.prop(uv, "snap_to_pixels")
186         layout.prop(uv, "constrain_to_image_bounds")
187
188         layout.separator()
189
190         layout.prop(uv, "live_unwrap")
191         layout.operator("uv.unwrap")
192         layout.operator("uv.pin", text="Unpin").clear = True
193         layout.operator("uv.pin")
194
195         layout.separator()
196
197         layout.operator("uv.pack_islands")
198         layout.operator("uv.average_islands_scale")
199         layout.operator("uv.minimize_stretch")
200         layout.operator("uv.stitch")
201
202         layout.separator()
203
204         layout.menu("IMAGE_MT_uvs_transform")
205         layout.menu("IMAGE_MT_uvs_mirror")
206         layout.menu("IMAGE_MT_uvs_weldalign")
207
208         layout.separator()
209
210         layout.prop_menu_enum(settings, "proportional_editing")
211         layout.prop_menu_enum(settings, "proportional_editing_falloff")
212
213         layout.separator()
214
215         layout.menu("IMAGE_MT_uvs_showhide")
216
217
218 class IMAGE_HT_header(bpy.types.Header):
219     bl_space_type = 'IMAGE_EDITOR'
220
221     def draw(self, context):
222         layout = self.layout
223
224         sima = context.space_data
225         ima = sima.image
226         iuser = sima.image_user
227         settings = context.tool_settings
228
229         # show_render = sima.show_render
230         # show_paint = sima.show_paint
231         show_uvedit = sima.show_uvedit
232
233         row = layout.row(align=True)
234         row.template_header()
235
236         # menus
237         if context.area.show_menus:
238             sub = row.row(align=True)
239             sub.menu("IMAGE_MT_view")
240
241             if show_uvedit:
242                 sub.menu("IMAGE_MT_select")
243
244             if ima and ima.dirty:
245                 sub.menu("IMAGE_MT_image", text="Image*")
246             else:
247                 sub.menu("IMAGE_MT_image", text="Image")
248
249             if show_uvedit:
250                 sub.menu("IMAGE_MT_uvs")
251
252         layout.template_ID(sima, "image", new="image.new")
253
254         # uv editing
255         if show_uvedit:
256             uvedit = sima.uv_editor
257
258             layout.prop(uvedit, "pivot", text="", icon_only=True)
259             layout.prop(settings, "uv_sync_selection", text="")
260
261             if settings.uv_sync_selection:
262                 layout.prop(settings, "mesh_selection_mode", text="", expand=True)
263             else:
264                 layout.prop(settings, "uv_selection_mode", text="", expand=True)
265                 layout.prop(uvedit, "sticky_selection_mode", text="", icon_only=True)
266
267             row = layout.row(align=True)
268             row.prop(settings, "snap", text="")
269             if settings.snap:
270                 row.prop(settings, "snap_mode", text="")
271
272             # mesh = context.edit_object.data
273             # row.prop_object(mesh, "active_uv_layer", mesh, "uv_textures")
274
275         if ima:
276             # layers
277             layout.template_image_layers(ima, iuser)
278
279             # painting
280             layout.prop(sima, "image_painting", text="")
281
282             # draw options
283             row = layout.row(align=True)
284             row.prop(sima, "draw_channels", text="", expand=True)
285
286             row = layout.row(align=True)
287             if ima.type == 'COMPOSITE':
288                 row.operator("image.record_composite", icon='ICON_REC')
289             if ima.type == 'COMPOSITE' and ima.source in ('MOVIE', 'SEQUENCE'):
290                 row.operator("image.play_composite", icon='ICON_PLAY')
291
292         if show_uvedit or sima.image_painting:
293             layout.prop(sima, "update_automatically", text="")
294
295
296 class IMAGE_PT_image_properties(bpy.types.Panel):
297     bl_space_type = 'IMAGE_EDITOR'
298     bl_region_type = 'UI'
299     bl_label = "Image"
300
301     def poll(self, context):
302         sima = context.space_data
303         return (sima.image)
304
305     def draw(self, context):
306         layout = self.layout
307
308         sima = context.space_data
309         # ima = sima.image
310         iuser = sima.image_user
311
312         layout.template_image(sima, "image", iuser, compact=True)
313
314
315 class IMAGE_PT_game_properties(bpy.types.Panel):
316     bl_space_type = 'IMAGE_EDITOR'
317     bl_region_type = 'UI'
318     bl_label = "Game Properties"
319
320     def poll(self, context):
321         rd = context.scene.render_data
322         sima = context.space_data
323         return (sima and sima.image) and (rd.engine == 'BLENDER_GAME')
324
325     def draw(self, context):
326         layout = self.layout
327
328         sima = context.space_data
329         ima = sima.image
330         wide_ui = context.region.width > narrowui
331
332         split = layout.split()
333
334         col = split.column()
335
336         sub = col.column(align=True)
337         sub.prop(ima, "animated")
338
339         subsub = sub.column()
340         subsub.active = ima.animated
341         subsub.prop(ima, "animation_start", text="Start")
342         subsub.prop(ima, "animation_end", text="End")
343         subsub.prop(ima, "animation_speed", text="Speed")
344
345         col.prop(ima, "tiles")
346         sub = col.column(align=True)
347         sub.active = ima.tiles or ima.animated
348         sub.prop(ima, "tiles_x", text="X")
349         sub.prop(ima, "tiles_y", text="Y")
350
351         if wide_ui:
352             col = split.column()
353         col.label(text="Clamp:")
354         col.prop(ima, "clamp_x", text="X")
355         col.prop(ima, "clamp_y", text="Y")
356         col.separator()
357         col.prop(ima, "mapping", expand=True)
358
359
360 class IMAGE_PT_view_properties(bpy.types.Panel):
361     bl_space_type = 'IMAGE_EDITOR'
362     bl_region_type = 'UI'
363     bl_label = "Display"
364
365     def poll(self, context):
366         sima = context.space_data
367         return (sima and (sima.image or sima.show_uvedit))
368
369     def draw(self, context):
370         layout = self.layout
371
372         sima = context.space_data
373         ima = sima.image
374         show_uvedit = sima.show_uvedit
375         uvedit = sima.uv_editor
376         wide_ui = context.region.width > narrowui
377
378         split = layout.split()
379
380         col = split.column()
381         if ima:
382             col.prop(ima, "display_aspect", text="Aspect Ratio")
383
384             if wide_ui:
385                 col = split.column()
386             col.label(text="Coordinates:")
387             col.prop(sima, "draw_repeated", text="Repeat")
388             if show_uvedit:
389                 col.prop(uvedit, "normalized_coordinates", text="Normalized")
390         elif show_uvedit:
391             col.label(text="Coordinates:")
392             col.prop(uvedit, "normalized_coordinates", text="Normalized")
393
394         if show_uvedit:
395
396             col = layout.column()
397             col.label(text="UVs:")
398             row = col.row()
399             if wide_ui:
400                 row.prop(uvedit, "edge_draw_type", expand=True)
401             else:
402                 row.prop(uvedit, "edge_draw_type", text="")
403
404             split = layout.split()
405             col = split.column()
406             col.prop(uvedit, "draw_smooth_edges", text="Smooth")
407             col.prop(uvedit, "draw_modified_edges", text="Modified")
408             #col.prop(uvedit, "draw_edges")
409             #col.prop(uvedit, "draw_faces")
410
411             if wide_ui:
412                 col = split.column()
413             col.prop(uvedit, "draw_stretch", text="Stretch")
414             sub = col.column()
415             sub.active = uvedit.draw_stretch
416             sub.row().prop(uvedit, "draw_stretch_type", expand=True)
417
418
419 class IMAGE_PT_paint(bpy.types.Panel):
420     bl_space_type = 'IMAGE_EDITOR'
421     bl_region_type = 'UI'
422     bl_label = "Paint"
423
424     def poll(self, context):
425         sima = context.space_data
426         return sima.show_paint
427
428     def draw(self, context):
429         layout = self.layout
430
431         settings = context.tool_settings.image_paint
432         brush = settings.brush
433         wide_ui = context.region.width > narrowui
434
435         col = layout.split().column()
436         row = col.row()
437         row.template_list(settings, "brushes", settings, "active_brush_index", rows=2)
438
439         col.template_ID(settings, "brush", new="brush.add")
440
441         if wide_ui:
442             sub = layout.row(align=True)
443         else:
444             sub = layout.column(align=True)
445         sub.prop_enum(settings, "tool", 'DRAW')
446         sub.prop_enum(settings, "tool", 'SOFTEN')
447         sub.prop_enum(settings, "tool", 'CLONE')
448         sub.prop_enum(settings, "tool", 'SMEAR')
449
450         if brush:
451             col = layout.column()
452             col.prop(brush, "color", text="")
453
454             row = col.row(align=True)
455             row.prop(brush, "size", slider=True)
456             row.prop(brush, "use_size_pressure", toggle=True, text="")
457
458             row = col.row(align=True)
459             row.prop(brush, "strength", slider=True)
460             row.prop(brush, "use_strength_pressure", toggle=True, text="")
461
462             row = col.row(align=True)
463             row.prop(brush, "jitter", slider=True)
464             row.prop(brush, "use_jitter_pressure", toggle=True, text="")
465
466             col.prop(brush, "blend", text="Blend")
467
468
469 class IMAGE_PT_paint_stroke(bpy.types.Panel):
470     bl_space_type = 'IMAGE_EDITOR'
471     bl_region_type = 'UI'
472     bl_label = "Paint Stroke"
473     bl_default_closed = True
474
475     def poll(self, context):
476         sima = context.space_data
477         settings = context.tool_settings.image_paint
478         return sima.show_paint and settings.brush
479
480     def draw(self, context):
481         layout = self.layout
482
483         settings = context.tool_settings.image_paint
484         brush = settings.brush
485
486         layout.prop(brush, "use_airbrush")
487         col = layout.column()
488         col.active = brush.use_airbrush
489         col.prop(brush, "rate", slider=True)
490
491         layout.prop(brush, "use_space")
492         row = layout.row(align=True)
493         row.active = brush.use_space
494         row.prop(brush, "spacing", text="Distance", slider=True)
495         row.prop(brush, "use_spacing_pressure", toggle=True, text="")
496
497
498 class IMAGE_PT_paint_curve(bpy.types.Panel):
499     bl_space_type = 'IMAGE_EDITOR'
500     bl_region_type = 'UI'
501     bl_label = "Paint Curve"
502     bl_default_closed = True
503
504     def poll(self, context):
505         sima = context.space_data
506         settings = context.tool_settings.image_paint
507         return sima.show_paint and settings.brush
508
509     def draw(self, context):
510         layout = self.layout
511
512         settings = context.tool_settings.image_paint
513         brush = settings.brush
514
515         layout.template_curve_mapping(brush, "curve")
516         layout.operator_menu_enum("brush.curve_preset", property="shape")
517
518 bpy.types.register(IMAGE_MT_view)
519 bpy.types.register(IMAGE_MT_select)
520 bpy.types.register(IMAGE_MT_image)
521 bpy.types.register(IMAGE_MT_uvs_showhide)
522 bpy.types.register(IMAGE_MT_uvs_transform)
523 bpy.types.register(IMAGE_MT_uvs_mirror)
524 bpy.types.register(IMAGE_MT_uvs_weldalign)
525 bpy.types.register(IMAGE_MT_uvs)
526 bpy.types.register(IMAGE_HT_header)
527 bpy.types.register(IMAGE_PT_image_properties)
528 bpy.types.register(IMAGE_PT_paint)
529 bpy.types.register(IMAGE_PT_paint_stroke)
530 bpy.types.register(IMAGE_PT_paint_curve)
531 bpy.types.register(IMAGE_PT_game_properties)
532 bpy.types.register(IMAGE_PT_view_properties)