Cleanup: strip trailing space, remove BOM
[blender-addons.git] / sun_position / ui_sun.py
blob49f04e337d7e2ea0f9cc99c595806d9468e8a02a
1 ### BEGIN GPL LICENSE BLOCK #####
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.
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.
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.
17 # ##### END GPL LICENSE BLOCK #####
19 import bpy
20 from bpy.types import Operator, Menu
21 from bl_operators.presets import AddPresetBase
22 import os
24 from .sun_calc import (format_lat_long, format_time, format_hms, sun)
27 # -------------------------------------------------------------------
28 # Choice list of places, month and day at 12:00 noon
29 # -------------------------------------------------------------------
32 class SUNPOS_MT_Presets(Menu):
33 bl_label = "Sun Position Presets"
34 preset_subdir = "operator/sun_position"
35 preset_operator = "script.execute_preset"
36 draw = Menu.draw_preset
39 class SUNPOS_OT_AddPreset(AddPresetBase, Operator):
40 '''Add Sun Position preset'''
41 bl_idname = "world.sunpos_add_preset"
42 bl_label = "Add Sun Position preset"
43 preset_menu = "SUNPOS_MT_Presets"
45 # variable used for all preset values
46 preset_defines = [
47 "sun_props = bpy.context.scene.sun_pos_properties"
50 # properties to store in the preset
51 preset_values = [
52 "sun_props.day",
53 "sun_props.month",
54 "sun_props.time",
55 "sun_props.year",
56 "sun_props.UTC_zone",
57 "sun_props.use_daylight_savings",
58 "sun_props.latitude",
59 "sun_props.longitude",
62 # where to store the preset
63 preset_subdir = "operator/sun_position"
66 # -------------------------------------------------------------------
68 # Draw the Sun Panel, sliders, et. al.
70 # -------------------------------------------------------------------
72 class SUNPOS_PT_Panel(bpy.types.Panel):
73 bl_space_type = "PROPERTIES"
74 bl_region_type = "WINDOW"
75 bl_context = "world"
76 bl_label = "Sun Position"
77 bl_options = {'DEFAULT_CLOSED'}
79 def draw(self, context):
80 sp = context.scene.sun_pos_properties
81 p = context.preferences.addons[__package__].preferences
82 layout = self.layout
83 self.draw_panel(context, sp, p, layout)
85 def draw_panel(self, context, sp, p, layout):
86 col = self.layout.column(align=True)
87 col.label(text="Usage Mode")
88 row = col.row()
89 row.prop(sp, "usage_mode", expand=True)
90 col.separator()
91 if sp.usage_mode == "HDR":
92 self.draw_environ_mode_panel(context, sp, p, layout)
93 else:
94 self.draw_normal_mode_panel(context, sp, p, layout)
96 def draw_environ_mode_panel(self, context, sp, p, layout):
97 flow = layout.grid_flow(row_major=True, columns=0, even_columns=True,
98 even_rows=False, align=False)
100 col = flow.column(align=True)
101 col.label(text="Environment Texture")
103 if context.scene.world is not None:
104 if context.scene.world.node_tree is not None:
105 col.prop_search(sp, "hdr_texture",
106 context.scene.world.node_tree, "nodes", text="")
107 else:
108 col.label(text="Please activate Use Nodes in the World panel.",
109 icon="ERROR")
110 else:
111 col.label(text="Please select World in the World panel.",
112 icon="ERROR")
114 col.separator()
116 col = flow.column(align=True)
117 col.label(text="Sun Object")
118 col.prop_search(sp, "sun_object",
119 context.view_layer, "objects", text="")
120 col.separator()
122 col = flow.column(align=True)
123 col.prop(sp, "sun_distance")
124 if not sp.bind_to_sun:
125 col.prop(sp, "hdr_elevation")
126 col.prop(sp, "hdr_azimuth")
127 col.separator()
129 col = flow.column(align=True)
130 if sp.bind_to_sun:
131 prop_text="Release binding"
132 else:
133 prop_text="Bind Texture to Sun "
134 col.prop(sp, "bind_to_sun", toggle=True, icon="CONSTRAINT",
135 text=prop_text)
137 row = col.row(align=True)
138 row.enabled = not sp.bind_to_sun
139 row.operator("world.sunpos_show_hdr", icon='LIGHT_SUN')
141 def draw_normal_mode_panel(self, context, sp, p, layout):
142 if p.show_time_place:
143 row = layout.row(align=True)
144 row.menu(SUNPOS_MT_Presets.__name__, text=SUNPOS_MT_Presets.bl_label)
145 row.operator(SUNPOS_OT_AddPreset.bl_idname, text="", icon='ADD')
146 row.operator(SUNPOS_OT_AddPreset.bl_idname, text="", icon='REMOVE').remove_active = True
148 col = layout.column(align=True)
149 col.use_property_split = True
150 col.use_property_decorate = False
151 col.prop(sp, "sun_object")
152 col.separator()
154 col.prop(sp, "object_collection")
155 if sp.object_collection:
156 col.prop(sp, "object_collection_type")
157 if sp.object_collection_type == 'DIURNAL':
158 col.prop(sp, "time_spread")
159 col.separator()
161 if context.scene.world is not None:
162 if context.scene.world.node_tree is not None:
163 col.prop_search(sp, "sky_texture",
164 context.scene.world.node_tree, "nodes")
165 else:
166 col.label(text="Please activate Use Nodes in the World panel.",
167 icon="ERROR")
168 else:
169 col.label(text="Please select World in the World panel.",
170 icon="ERROR")
172 class SUNPOS_PT_Location(bpy.types.Panel):
173 bl_space_type = "PROPERTIES"
174 bl_region_type = "WINDOW"
175 bl_context = "world"
176 bl_label = "Location"
177 bl_parent_id = "SUNPOS_PT_Panel"
179 @classmethod
180 def poll(self, context):
181 sp = context.scene.sun_pos_properties
182 return sp.usage_mode != "HDR"
184 def draw(self, context):
185 layout = self.layout
186 sp = context.scene.sun_pos_properties
187 p = context.preferences.addons[__package__].preferences
189 col = layout.column(align=True)
190 col.label(text="Enter Coordinates")
191 col.prop(sp, "co_parser", text='', icon='URL')
193 layout.separator()
195 flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
197 col = flow.column(align=True)
198 col.prop(sp, "latitude")
199 if p.show_dms:
200 row = col.row()
201 row.alignment = 'RIGHT'
202 row.label(text=format_lat_long(sp.latitude, True))
204 col = flow.column(align=True)
205 col.prop(sp, "longitude")
206 if p.show_dms:
207 row = col.row()
208 row.alignment = 'RIGHT'
209 row.label(text=format_lat_long(sp.longitude, False))
210 col.separator()
212 if p.show_north:
213 col = flow.column(align=True)
214 col.prop(sp, "show_north", toggle=True)
215 col.prop(sp, "north_offset")
216 col.separator()
218 if p.show_az_el:
219 col = flow.column(align=True)
220 row = col.row()
221 row.alignment = 'RIGHT'
222 row.label(text="Azimuth: " +
223 str(round(sun.azimuth, 3)) + "°")
224 row = col.row()
225 row.alignment = 'RIGHT'
226 row.label(text="Elevation: " +
227 str(round(sun.elevation, 3)) + "°")
228 col.separator()
230 if p.show_refraction:
231 col = flow.column()
232 col.prop(sp, "use_refraction")
233 col.separator()
235 col = flow.column()
236 col.prop(sp, "sun_distance")
239 class SUNPOS_PT_Time(bpy.types.Panel):
240 bl_space_type = "PROPERTIES"
241 bl_region_type = "WINDOW"
242 bl_context = "world"
243 bl_label = "Time"
244 bl_parent_id = "SUNPOS_PT_Panel"
246 @classmethod
247 def poll(self, context):
248 sp = context.scene.sun_pos_properties
249 return sp.usage_mode != "HDR"
251 def draw(self, context):
252 layout = self.layout
253 sp = context.scene.sun_pos_properties
254 p = context.preferences.addons[__package__].preferences
256 flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
258 col = flow.column(align=True)
259 col.prop(sp, "use_day_of_year",
260 icon='SORTTIME')
261 if sp.use_day_of_year:
262 col.prop(sp, "day_of_year")
263 else:
264 col.prop(sp, "day")
265 col.prop(sp, "month")
266 col.prop(sp, "year")
267 col.separator()
269 col = flow.column(align=True)
270 col.prop(sp, "time")
271 col.prop(sp, "UTC_zone")
272 if p.show_daylight_savings:
273 col.prop(sp, "use_daylight_savings")
274 col.separator()
276 col = flow.column(align=True)
277 lt = format_time(sp.time,
278 p.show_daylight_savings and sp.use_daylight_savings,
279 sp.longitude)
280 ut = format_time(sp.time,
281 p.show_daylight_savings and sp.use_daylight_savings,
282 sp.longitude,
283 sp.UTC_zone)
284 col.alignment = 'CENTER'
285 col.label(text="Local: " + lt, icon='TIME')
286 col.label(text=" UTC: " + ut, icon='PREVIEW_RANGE')
287 col.separator()
289 col = flow.column(align=True)
290 col.alignment = 'CENTER'
291 if p.show_rise_set:
292 sr = format_hms(sun.sunrise.time)
293 ss = format_hms(sun.sunset.time)
294 tsr = "Sunrise: " + sr
295 tss = " Sunset: " + ss
296 col.label(text=tsr, icon='LIGHT_SUN')
297 col.label(text=tss, icon='SOLO_ON')