Tweaked Cache panels to make them clearer, simpler, and added single column UI.
[blender.git] / release / scripts / ui / properties_physics_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 narrowui = 180
22
23
24 def point_cache_ui(self, context, cache, enabled, particles, smoke):
25     layout = self.layout
26
27     wide_ui = context.region.width > narrowui
28     layout.set_context_pointer("PointCache", cache)
29
30     row = layout.row()
31     row.template_list(cache, "point_cache_list", cache, "active_point_cache_index", rows=2)
32     col = row.column(align=True)
33     col.operator("ptcache.add", icon='ZOOMIN', text="")
34     col.operator("ptcache.remove", icon='ZOOMOUT', text="")
35
36     row = layout.row()
37     if particles:
38         row.prop(cache, "external")
39
40     if cache.external:
41         split = layout.split(percentage=0.80)
42         split.prop(cache, "name", text="File Name")
43         split.prop(cache, "index", text="")
44
45         layout.label(text="File Path:")
46         layout.prop(cache, "filepath", text="")
47
48         layout.label(text=cache.info)
49     else:
50         layout.prop(cache, "name", text="File Name")
51         
52         split = layout.split()
53         col = split.column(align=True)
54         
55         if not particles:
56             
57             col.enabled = enabled
58             col.prop(cache, "frame_start")
59             col.prop(cache, "frame_end")
60         if not smoke:
61             col.prop(cache, "step")
62
63         if wide_ui:
64             col = split.column()
65
66         if not smoke:
67             sub = col.column()
68             sub.enabled = enabled
69             sub.prop(cache, "quick_cache")
70             col.prop(cache, "disk_cache")
71             col.label(text=cache.info)
72
73         
74
75         layout.separator()
76         
77         split = layout.split()
78         
79         col = split.column()
80         
81         if cache.baked == True:
82             col.operator("ptcache.free_bake", text="Free Bake")
83         else:
84             col.operator("ptcache.bake", text="Bake").bake = True
85         
86         sub = col.row()
87         sub.enabled = (cache.frames_skipped or cache.outdated) and enabled
88         sub.operator("ptcache.bake", text="Calculate To Frame").bake = False
89
90         sub = col.column()
91         sub.enabled = enabled
92         sub.operator("ptcache.bake_from_cache", text="Current Cache to Bake")
93         
94         
95         if wide_ui:
96             col = split.column()
97         col.operator("ptcache.bake_all", text="Bake All Dynamics").bake = True
98         col.operator("ptcache.free_bake_all", text="Free All Bakes")
99         col.operator("ptcache.bake_all", text="Update All To Frame").bake = False
100
101
102 def effector_weights_ui(self, context, weights):
103     layout = self.layout
104
105     wide_ui = context.region.width > narrowui
106
107     layout.prop(weights, "group")
108
109     split = layout.split()
110
111     col = split.column()
112     col.prop(weights, "gravity", slider=True)
113
114     if wide_ui:
115         col = split.column()
116     col.prop(weights, "all", slider=True)
117
118     layout.separator()
119
120     split = layout.split()
121
122     col = split.column()
123     col.prop(weights, "force", slider=True)
124     col.prop(weights, "vortex", slider=True)
125     col.prop(weights, "magnetic", slider=True)
126     col.prop(weights, "wind", slider=True)
127     col.prop(weights, "curveguide", slider=True)
128     col.prop(weights, "texture", slider=True)
129
130     if wide_ui:
131         col = split.column()
132     col.prop(weights, "harmonic", slider=True)
133     col.prop(weights, "charge", slider=True)
134     col.prop(weights, "lennardjones", slider=True)
135     col.prop(weights, "turbulence", slider=True)
136     col.prop(weights, "drag", slider=True)
137     col.prop(weights, "boid", slider=True)
138
139
140 def basic_force_field_settings_ui(self, context, field):
141     layout = self.layout
142
143     wide_ui = context.region.width > narrowui
144
145     split = layout.split()
146
147     if not field or field.type == 'NONE':
148         return
149
150     col = split.column()
151
152     if field.type == 'DRAG':
153         col.prop(field, "linear_drag", text="Linear")
154     else:
155         col.prop(field, "strength")
156
157     if field.type == 'TURBULENCE':
158         col.prop(field, "size")
159         col.prop(field, "flow")
160     elif field.type == 'HARMONIC':
161         col.prop(field, "harmonic_damping", text="Damping")
162         col.prop(field, "rest_length")
163     elif field.type == 'VORTEX' and field.shape != 'POINT':
164         col.prop(field, "inflow")
165     elif field.type == 'DRAG':
166         col.prop(field, "quadratic_drag", text="Quadratic")
167     else:
168         col.prop(field, "flow")
169
170     if wide_ui:
171         col = split.column()
172     col.prop(field, "noise")
173     col.prop(field, "seed")
174     if field.type == 'TURBULENCE':
175         col.prop(field, "global_coordinates", text="Global")
176     elif field.type == 'HARMONIC':
177         col.prop(field, "multiple_springs")
178
179     split = layout.split()
180
181     col = split.column()
182     col.label(text="Effect point:")
183     col.prop(field, "do_location")
184     col.prop(field, "do_rotation")
185
186     if wide_ui:
187         col = split.column()
188     col.label(text="Collision:")
189     col.prop(field, "do_absorption")
190
191
192 def basic_force_field_falloff_ui(self, context, field):
193     layout = self.layout
194
195     wide_ui = context.region.width > narrowui
196
197     # XXX: This doesn't update for some reason.
198     #if wide_ui:
199     #    split = layout.split()
200     #else:
201     split = layout.split(percentage=0.35)
202
203     if not field or field.type == 'NONE':
204         return
205
206     col = split.column()
207     col.prop(field, "z_direction", text="")
208     col.prop(field, "use_min_distance", text="Use Minimum")
209     col.prop(field, "use_max_distance", text="Use Maximum")
210
211     if wide_ui:
212         col = split.column()
213     col.prop(field, "falloff_power", text="Power")
214
215     sub = col.column()
216     sub.active = field.use_min_distance
217     sub.prop(field, "minimum_distance", text="Distance")
218
219     sub = col.column()
220     sub.active = field.use_max_distance
221     sub.prop(field, "maximum_distance", text="Distance")
222
223
224 def register():
225     pass
226
227
228 def unregister():
229     pass
230
231 if __name__ == "__main__":
232     register()