Moving classes to separate listing broke panel order
[blender-staging.git] / release / scripts / startup / bl_ui / properties_world.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 import bpy
21 from bpy.types import Panel
22 from rna_prop_ui import PropertyPanel
23
24
25 class WorldButtonsPanel:
26     bl_space_type = 'PROPERTIES'
27     bl_region_type = 'WINDOW'
28     bl_context = "world"
29     # COMPAT_ENGINES must be defined in each subclass, external engines can add themselves here
30
31     @classmethod
32     def poll(cls, context):
33         return (context.world and context.scene.render.engine in cls.COMPAT_ENGINES)
34
35
36 class WORLD_PT_context_world(WorldButtonsPanel, Panel):
37     bl_label = ""
38     bl_options = {'HIDE_HEADER'}
39     COMPAT_ENGINES = {'BLENDER_RENDER'}
40
41     @classmethod
42     def poll(cls, context):
43         rd = context.scene.render
44         return rd.engine in cls.COMPAT_ENGINES
45
46     def draw(self, context):
47         layout = self.layout
48
49         scene = context.scene
50         world = context.world
51         space = context.space_data
52
53         texture_count = world and len(world.texture_slots.keys())
54
55         split = layout.split(percentage=0.85)
56         if scene:
57             split.template_ID(scene, "world", new="world.new")
58         elif world:
59             split.template_ID(space, "pin_id")
60
61         if texture_count:
62             split.label(text=str(texture_count), icon='TEXTURE')
63
64
65 class WORLD_PT_preview(WorldButtonsPanel, Panel):
66     bl_label = "Preview"
67     COMPAT_ENGINES = {'BLENDER_RENDER'}
68
69     @classmethod
70     def poll(cls, context):
71         rd = context.scene.render
72         return (context.world) and (rd.engine in cls.COMPAT_ENGINES)
73
74     def draw(self, context):
75         self.layout.template_preview(context.world)
76
77
78 class WORLD_PT_world(WorldButtonsPanel, Panel):
79     bl_label = "World"
80     COMPAT_ENGINES = {'BLENDER_RENDER'}
81
82     def draw(self, context):
83         layout = self.layout
84
85         world = context.world
86
87         row = layout.row()
88         row.prop(world, "use_sky_paper")
89         row.prop(world, "use_sky_blend")
90         row.prop(world, "use_sky_real")
91
92         row = layout.row()
93         row.column().prop(world, "horizon_color")
94         col = row.column()
95         col.prop(world, "zenith_color")
96         col.active = world.use_sky_blend
97         row.column().prop(world, "ambient_color")
98
99         row = layout.row()
100         row.prop(world, "exposure")
101         row.prop(world, "color_range")
102
103
104 class WORLD_PT_ambient_occlusion(WorldButtonsPanel, Panel):
105     bl_label = "Ambient Occlusion"
106     COMPAT_ENGINES = {'BLENDER_RENDER'}
107
108     def draw_header(self, context):
109         light = context.world.light_settings
110         self.layout.prop(light, "use_ambient_occlusion", text="")
111
112     def draw(self, context):
113         layout = self.layout
114
115         light = context.world.light_settings
116
117         layout.active = light.use_ambient_occlusion
118
119         split = layout.split()
120         split.prop(light, "ao_factor", text="Factor")
121         split.prop(light, "ao_blend_type", text="")
122
123
124 class WORLD_PT_environment_lighting(WorldButtonsPanel, Panel):
125     bl_label = "Environment Lighting"
126     COMPAT_ENGINES = {'BLENDER_RENDER'}
127
128     def draw_header(self, context):
129         light = context.world.light_settings
130         self.layout.prop(light, "use_environment_light", text="")
131
132     def draw(self, context):
133         layout = self.layout
134
135         light = context.world.light_settings
136
137         layout.active = light.use_environment_light
138
139         split = layout.split()
140         split.prop(light, "environment_energy", text="Energy")
141         split.prop(light, "environment_color", text="")
142
143
144 class WORLD_PT_indirect_lighting(WorldButtonsPanel, Panel):
145     bl_label = "Indirect Lighting"
146     COMPAT_ENGINES = {'BLENDER_RENDER'}
147
148     def draw_header(self, context):
149         light = context.world.light_settings
150         self.layout.prop(light, "use_indirect_light", text="")
151
152     def draw(self, context):
153         layout = self.layout
154
155         light = context.world.light_settings
156
157         layout.active = light.use_indirect_light and light.gather_method == 'APPROXIMATE'
158
159         split = layout.split()
160         split.prop(light, "indirect_factor", text="Factor")
161         split.prop(light, "indirect_bounces", text="Bounces")
162
163         if light.gather_method == 'RAYTRACE':
164             layout.label(text="Only works with Approximate gather method")
165
166
167 class WORLD_PT_gather(WorldButtonsPanel, Panel):
168     bl_label = "Gather"
169     COMPAT_ENGINES = {'BLENDER_RENDER'}
170
171     def draw(self, context):
172         layout = self.layout
173
174         light = context.world.light_settings
175
176         layout.active = light.use_ambient_occlusion or light.use_environment_light or light.use_indirect_light
177
178         layout.prop(light, "gather_method", expand=True)
179
180         split = layout.split()
181
182         col = split.column()
183         col.label(text="Attenuation:")
184         if light.gather_method == 'RAYTRACE':
185             col.prop(light, "distance")
186         col.prop(light, "use_falloff")
187         sub = col.row()
188         sub.active = light.use_falloff
189         sub.prop(light, "falloff_strength", text="Strength")
190
191         if light.gather_method == 'RAYTRACE':
192             col = split.column()
193
194             col.label(text="Sampling:")
195             col.prop(light, "sample_method", text="")
196
197             sub = col.column()
198             sub.prop(light, "samples")
199
200             if light.sample_method == 'ADAPTIVE_QMC':
201                 sub.prop(light, "threshold")
202                 sub.prop(light, "adapt_to_speed", slider=True)
203             elif light.sample_method == 'CONSTANT_JITTERED':
204                 sub.prop(light, "bias")
205
206         if light.gather_method == 'APPROXIMATE':
207             col = split.column()
208
209             col.label(text="Sampling:")
210             col.prop(light, "passes")
211             col.prop(light, "error_threshold", text="Error")
212             col.prop(light, "use_cache")
213             col.prop(light, "correction")
214
215
216 class WORLD_PT_mist(WorldButtonsPanel, Panel):
217     bl_label = "Mist"
218     bl_options = {'DEFAULT_CLOSED'}
219     COMPAT_ENGINES = {'BLENDER_RENDER'}
220
221     def draw_header(self, context):
222         world = context.world
223
224         self.layout.prop(world.mist_settings, "use_mist", text="")
225
226     def draw(self, context):
227         layout = self.layout
228
229         world = context.world
230
231         layout.active = world.mist_settings.use_mist
232
233         split = layout.split()
234
235         col = split.column()
236         col.prop(world.mist_settings, "intensity")
237         col.prop(world.mist_settings, "start")
238
239         col = split.column()
240         col.prop(world.mist_settings, "depth")
241         col.prop(world.mist_settings, "height")
242
243         layout.prop(world.mist_settings, "falloff")
244
245
246 class WORLD_PT_custom_props(WorldButtonsPanel, PropertyPanel, Panel):
247     COMPAT_ENGINES = {'BLENDER_RENDER', 'BLENDER_GAME'}
248     _context_path = "world"
249     _property_type = bpy.types.World
250
251
252 classes = (
253     WORLD_PT_context_world,
254     WORLD_PT_preview,
255     WORLD_PT_world,
256     WORLD_PT_ambient_occlusion,
257     WORLD_PT_environment_lighting,
258     WORLD_PT_indirect_lighting,
259     WORLD_PT_gather,
260     WORLD_PT_mist,
261     WORLD_PT_custom_props,
262 )
263
264 if __name__ == "__main__":  # only for live edit.
265     from bpy.utils import register_class
266     for cls in classes:
267         register_class(cls)