Sun Position: group some prefs under show_overlays
[blender-addons.git] / sun_position / ui_sun.py
blob000532d6346101a50627cc0a5d489d7ce8dc361a
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 layout = self.layout
83 layout.use_property_split = True
85 col = layout.column(align=True)
86 if context.scene.world is not None:
87 if context.scene.world.node_tree is not None:
88 col.prop_search(sp, "hdr_texture",
89 context.scene.world.node_tree, "nodes")
90 else:
91 col.label(text="Please activate Use Nodes in the World panel.",
92 icon="ERROR")
93 else:
94 col.label(text="Please select World in the World panel.",
95 icon="ERROR")
96 col.prop_search(sp, "sun_object",
97 context.view_layer, "objects")
99 col = layout.column(align=True)
100 col.prop(sp, "bind_to_sun", text="Bind Texture to Sun")
101 col.prop(sp, "hdr_azimuth")
102 row = col.row(align=True)
103 row.active = not sp.bind_to_sun
104 row.prop(sp, "hdr_elevation")
105 col.prop(sp, "sun_distance")
106 col.separator()
108 col = layout.column(align=True)
109 row = col.row(align=True)
110 row.enabled = not sp.bind_to_sun
111 row.operator("world.sunpos_show_hdr", icon='LIGHT_SUN')
113 def draw_normal_mode_panel(self, context, sp, p, layout):
114 if p.show_time_place:
115 row = layout.row(align=True)
116 row.menu(SUNPOS_MT_Presets.__name__, text=SUNPOS_MT_Presets.bl_label)
117 row.operator(SUNPOS_OT_AddPreset.bl_idname, text="", icon='ADD')
118 row.operator(SUNPOS_OT_AddPreset.bl_idname, text="", icon='REMOVE').remove_active = True
120 col = layout.column(align=True)
121 col.use_property_split = True
122 col.use_property_decorate = False
123 col.prop(sp, "sun_object")
124 col.separator()
126 col.prop(sp, "object_collection")
127 if sp.object_collection:
128 col.prop(sp, "object_collection_type")
129 if sp.object_collection_type == 'DIURNAL':
130 col.prop(sp, "time_spread")
131 col.separator()
133 if context.scene.world is not None:
134 if context.scene.world.node_tree is not None:
135 col.prop_search(sp, "sky_texture",
136 context.scene.world.node_tree, "nodes")
137 else:
138 col.label(text="Please activate Use Nodes in the World panel.",
139 icon="ERROR")
140 else:
141 col.label(text="Please select World in the World panel.",
142 icon="ERROR")
145 class SUNPOS_PT_Location(bpy.types.Panel):
146 bl_space_type = "PROPERTIES"
147 bl_region_type = "WINDOW"
148 bl_context = "world"
149 bl_label = "Location"
150 bl_parent_id = "SUNPOS_PT_Panel"
152 @classmethod
153 def poll(self, context):
154 sp = context.scene.sun_pos_properties
155 return sp.usage_mode != "HDR"
157 def draw(self, context):
158 layout = self.layout
159 sp = context.scene.sun_pos_properties
160 p = context.preferences.addons[__package__].preferences
162 col = layout.column(align=True)
163 col.label(text="Enter Coordinates")
164 col.prop(sp, "co_parser", text='', icon='URL')
166 layout.separator()
168 flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
170 col = flow.column(align=True)
171 col.prop(sp, "latitude")
172 if p.show_dms:
173 row = col.row()
174 row.alignment = 'RIGHT'
175 row.label(text=format_lat_long(sp.latitude, True))
177 col = flow.column(align=True)
178 col.prop(sp, "longitude")
179 if p.show_dms:
180 row = col.row()
181 row.alignment = 'RIGHT'
182 row.label(text=format_lat_long(sp.longitude, False))
183 col.separator()
185 if p.show_overlays:
186 col = flow.column(align=True)
187 col.prop(sp, "show_north", toggle=True)
188 col.prop(sp, "north_offset")
189 col.separator()
191 if p.show_overlays:
192 col = flow.column(align=True)
193 col.prop(sp, "show_surface", toggle=True)
194 col.prop(sp, "show_analemmas", toggle=True)
195 col.separator()
197 if p.show_az_el:
198 col = flow.column(align=True)
199 split = col.split(factor=0.4, align=True)
200 split.label(text="Azimuth:")
201 split.label(text=str(round(degrees(sun.azimuth), 3)) + "°")
202 split = col.split(factor=0.4, align=True)
203 split.label(text="Elevation:")
204 split.label(text=str(round(degrees(sun.elevation), 3)) + "°")
205 col.separator()
207 if p.show_refraction:
208 col = flow.column()
209 col.prop(sp, "use_refraction")
210 col.separator()
212 col = flow.column()
213 col.prop(sp, "sun_distance")
214 col.separator()
217 class SUNPOS_PT_Time(bpy.types.Panel):
218 bl_space_type = "PROPERTIES"
219 bl_region_type = "WINDOW"
220 bl_context = "world"
221 bl_label = "Time"
222 bl_parent_id = "SUNPOS_PT_Panel"
224 @classmethod
225 def poll(self, context):
226 sp = context.scene.sun_pos_properties
227 return sp.usage_mode != "HDR"
229 def draw(self, context):
230 layout = self.layout
231 sp = context.scene.sun_pos_properties
232 p = context.preferences.addons[__package__].preferences
234 flow = layout.grid_flow(row_major=True, columns=0, even_columns=True, even_rows=False, align=False)
236 col = flow.column(align=True)
237 col.prop(sp, "use_day_of_year",
238 icon='SORTTIME')
239 if sp.use_day_of_year:
240 col.prop(sp, "day_of_year")
241 else:
242 col.prop(sp, "day")
243 col.prop(sp, "month")
244 col.prop(sp, "year")
245 col.separator()
247 col = flow.column(align=True)
248 col.prop(sp, "time", text="Time", text_ctxt="Hour")
249 col.prop(sp, "UTC_zone")
250 if p.show_daylight_savings:
251 col.prop(sp, "use_daylight_savings")
252 col.separator()
254 col = flow.column(align=True)
255 lt = format_time(sp.time,
256 p.show_daylight_savings and sp.use_daylight_savings,
257 sp.longitude)
258 ut = format_time(sp.time,
259 p.show_daylight_savings and sp.use_daylight_savings,
260 sp.longitude,
261 sp.UTC_zone)
262 col.alignment = 'CENTER'
264 split = col.split(factor=0.5, align=True)
265 split.label(text="Local:", icon='TIME')
266 split.label(text=lt)
267 split = col.split(factor=0.5, align=True)
268 split.label(text="UTC:", icon='PREVIEW_RANGE')
269 split.label(text=ut)
270 col.separator()
272 col = flow.column(align=True)
273 col.alignment = 'CENTER'
274 if p.show_rise_set:
275 sr = format_hms(sun.sunrise)
276 ss = format_hms(sun.sunset)
278 split = col.split(factor=0.5, align=True)
279 split.label(text="Sunrise:", icon='LIGHT_SUN')
280 split.label(text=sr)
281 split = col.split(factor=0.5, align=True)
282 split.label(text="Sunset:", icon='SOLO_ON')
283 split.label(text=ss)
285 col.separator()