Sun Position: Cleanup: simplify the Sun Properties, get rid of TAzEl
[blender-addons.git] / sun_position / ui_sun.py
blobe8a0f31c102e6ca664158ca6f7056283c1d7973e
1 # SPDX-License-Identifier: GPL-2.0-or-later
3 import bpy
4 from bpy.types import Operator, Menu
5 from bl_operators.presets import AddPresetBase
6 import os
7 from math import degrees
9 from .sun_calc import (format_lat_long, format_time, format_hms, sun)
12 # -------------------------------------------------------------------
13 # Choice list of places, month and day at 12:00 noon
14 # -------------------------------------------------------------------
17 class SUNPOS_MT_Presets(Menu):
18 bl_label = "Sun Position Presets"
19 preset_subdir = "operator/sun_position"
20 preset_operator = "script.execute_preset"
21 draw = Menu.draw_preset
24 class SUNPOS_OT_AddPreset(AddPresetBase, Operator):
25 '''Add Sun Position preset'''
26 bl_idname = "world.sunpos_add_preset"
27 bl_label = "Add Sun Position preset"
28 preset_menu = "SUNPOS_MT_Presets"
30 # variable used for all preset values
31 preset_defines = [
32 "sun_props = bpy.context.scene.sun_pos_properties"
35 # properties to store in the preset
36 preset_values = [
37 "sun_props.day",
38 "sun_props.month",
39 "sun_props.time",
40 "sun_props.year",
41 "sun_props.UTC_zone",
42 "sun_props.use_daylight_savings",
43 "sun_props.latitude",
44 "sun_props.longitude",
47 # where to store the preset
48 preset_subdir = "operator/sun_position"
51 # -------------------------------------------------------------------
53 # Draw the Sun Panel, sliders, et. al.
55 # -------------------------------------------------------------------
57 class SUNPOS_PT_Panel(bpy.types.Panel):
58 bl_space_type = "PROPERTIES"
59 bl_region_type = "WINDOW"
60 bl_context = "world"
61 bl_label = "Sun Position"
62 bl_options = {'DEFAULT_CLOSED'}
64 def draw(self, context):
65 sp = context.scene.sun_pos_properties
66 p = context.preferences.addons[__package__].preferences
67 layout = self.layout
68 self.draw_panel(context, sp, p, layout)
70 def draw_panel(self, context, sp, p, layout):
71 col = self.layout.column(align=True)
72 col.label(text="Usage Mode")
73 row = col.row()
74 row.prop(sp, "usage_mode", expand=True)
75 col.separator()
76 if sp.usage_mode == "HDR":
77 self.draw_environ_mode_panel(context, sp, p, layout)
78 else:
79 self.draw_normal_mode_panel(context, sp, p, layout)
81 def draw_environ_mode_panel(self, context, sp, p, layout):
82 flow = layout.grid_flow(row_major=True, columns=0, even_columns=True,
83 even_rows=False, align=False)
85 col = flow.column(align=True)
86 col.label(text="Environment Texture")
88 if context.scene.world is not None:
89 if context.scene.world.node_tree is not None:
90 col.prop_search(sp, "hdr_texture",
91 context.scene.world.node_tree, "nodes", text="")
92 else:
93 col.label(text="Please activate Use Nodes in the World panel.",
94 icon="ERROR")
95 else:
96 col.label(text="Please select World in the World panel.",
97 icon="ERROR")
99 col.separator()
101 col = flow.column(align=True)
102 col.label(text="Sun Object")
103 col.prop_search(sp, "sun_object",
104 context.view_layer, "objects", text="")
105 col.separator()
107 col = flow.column(align=True)
108 col.prop(sp, "sun_distance")
109 if not sp.bind_to_sun:
110 col.prop(sp, "hdr_elevation")
111 col.prop(sp, "hdr_azimuth")
112 col.separator()
114 col = flow.column(align=True)
115 if sp.bind_to_sun:
116 col.prop(sp, "bind_to_sun", toggle=True, icon="CONSTRAINT",
117 text="Release binding")
118 else:
119 col.prop(sp, "bind_to_sun", toggle=True, icon="CONSTRAINT",
120 text="Bind Texture to Sun")
122 row = col.row(align=True)
123 row.enabled = not sp.bind_to_sun
124 row.operator("world.sunpos_show_hdr", icon='LIGHT_SUN')
126 def draw_normal_mode_panel(self, context, sp, p, layout):
127 if p.show_time_place:
128 row = layout.row(align=True)
129 row.menu(SUNPOS_MT_Presets.__name__, text=SUNPOS_MT_Presets.bl_label)
130 row.operator(SUNPOS_OT_AddPreset.bl_idname, text="", icon='ADD')
131 row.operator(SUNPOS_OT_AddPreset.bl_idname, text="", icon='REMOVE').remove_active = True
133 col = layout.column(align=True)
134 col.use_property_split = True
135 col.use_property_decorate = False
136 col.prop(sp, "sun_object")
137 col.separator()
139 col.prop(sp, "object_collection")
140 if sp.object_collection:
141 col.prop(sp, "object_collection_type")
142 if sp.object_collection_type == 'DIURNAL':
143 col.prop(sp, "time_spread")
144 col.separator()
146 if context.scene.world is not None:
147 if context.scene.world.node_tree is not None:
148 col.prop_search(sp, "sky_texture",
149 context.scene.world.node_tree, "nodes")
150 else:
151 col.label(text="Please activate Use Nodes in the World panel.",
152 icon="ERROR")
153 else:
154 col.label(text="Please select World in the World panel.",
155 icon="ERROR")
158 class SUNPOS_PT_Location(bpy.types.Panel):
159 bl_space_type = "PROPERTIES"
160 bl_region_type = "WINDOW"
161 bl_context = "world"
162 bl_label = "Location"
163 bl_parent_id = "SUNPOS_PT_Panel"
165 @classmethod
166 def poll(self, context):
167 sp = context.scene.sun_pos_properties
168 return sp.usage_mode != "HDR"
170 def draw(self, context):
171 layout = self.layout
172 sp = context.scene.sun_pos_properties
173 p = context.preferences.addons[__package__].preferences
175 col = layout.column(align=True)
176 col.label(text="Enter Coordinates")
177 col.prop(sp, "co_parser", text='', icon='URL')
179 layout.separator()
181 flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
183 col = flow.column(align=True)
184 col.prop(sp, "latitude")
185 if p.show_dms:
186 row = col.row()
187 row.alignment = 'RIGHT'
188 row.label(text=format_lat_long(sp.latitude, True))
190 col = flow.column(align=True)
191 col.prop(sp, "longitude")
192 if p.show_dms:
193 row = col.row()
194 row.alignment = 'RIGHT'
195 row.label(text=format_lat_long(sp.longitude, False))
196 col.separator()
198 if p.show_north:
199 col = flow.column(align=True)
200 col.prop(sp, "show_north", toggle=True)
201 col.prop(sp, "north_offset")
202 col.separator()
204 if p.show_surface or p.show_analemmas:
205 col = flow.column(align=True)
206 if p.show_surface:
207 col.prop(sp, "show_surface", toggle=True)
208 if p.show_analemmas:
209 col.prop(sp, "show_analemmas", toggle=True)
210 col.separator()
212 if p.show_az_el:
213 col = flow.column(align=True)
214 split = col.split(factor=0.4, align=True)
215 split.label(text="Azimuth:")
216 split.label(text=str(round(degrees(sun.azimuth), 3)) + "°")
217 split = col.split(factor=0.4, align=True)
218 split.label(text="Elevation:")
219 split.label(text=str(round(degrees(sun.elevation), 3)) + "°")
220 col.separator()
222 if p.show_refraction:
223 col = flow.column()
224 col.prop(sp, "use_refraction")
225 col.separator()
227 col = flow.column()
228 col.prop(sp, "sun_distance")
229 col.separator()
232 class SUNPOS_PT_Time(bpy.types.Panel):
233 bl_space_type = "PROPERTIES"
234 bl_region_type = "WINDOW"
235 bl_context = "world"
236 bl_label = "Time"
237 bl_parent_id = "SUNPOS_PT_Panel"
239 @classmethod
240 def poll(self, context):
241 sp = context.scene.sun_pos_properties
242 return sp.usage_mode != "HDR"
244 def draw(self, context):
245 layout = self.layout
246 sp = context.scene.sun_pos_properties
247 p = context.preferences.addons[__package__].preferences
249 flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
251 col = flow.column(align=True)
252 col.prop(sp, "use_day_of_year",
253 icon='SORTTIME')
254 if sp.use_day_of_year:
255 col.prop(sp, "day_of_year")
256 else:
257 col.prop(sp, "day")
258 col.prop(sp, "month")
259 col.prop(sp, "year")
260 col.separator()
262 col = flow.column(align=True)
263 col.prop(sp, "time")
264 col.prop(sp, "UTC_zone")
265 if p.show_daylight_savings:
266 col.prop(sp, "use_daylight_savings")
267 col.separator()
269 col = flow.column(align=True)
270 lt = format_time(sp.time,
271 p.show_daylight_savings and sp.use_daylight_savings,
272 sp.longitude)
273 ut = format_time(sp.time,
274 p.show_daylight_savings and sp.use_daylight_savings,
275 sp.longitude,
276 sp.UTC_zone)
277 col.alignment = 'CENTER'
279 split = col.split(factor=0.5, align=True)
280 split.label(text="Local:", icon='TIME')
281 split.label(text=lt)
282 split = col.split(factor=0.5, align=True)
283 split.label(text="UTC:", icon='PREVIEW_RANGE')
284 split.label(text=ut)
285 col.separator()
287 col = flow.column(align=True)
288 col.alignment = 'CENTER'
289 if p.show_rise_set:
290 sr = format_hms(sun.sunrise)
291 ss = format_hms(sun.sunset)
293 split = col.split(factor=0.5, align=True)
294 split.label(text="Sunrise:", icon='LIGHT_SUN')
295 split.label(text=sr)
296 split = col.split(factor=0.5, align=True)
297 split.label(text="Sunset:", icon='SOLO_ON')
298 split.label(text=ss)
300 col.separator()