import bpy
import textwrap
from mathutils import Vector
from .. module import module_name
def get_dpi_factor(force=False):
return get_dpi(force=force) / 72
def get_dpi(force=False):
preference = bpy.context.preferences.addons[module_name()].preferences
if preference.ui.use_dpi_factoring or force:
systemPreferences = bpy.context.preferences.system
retinaFactor = systemPreferences.pixel_size
if bpy.app.version[:2] > (3, 3):
retinaFactor /= bpy.context.preferences.system.ui_line_width
return int(systemPreferences.dpi * retinaFactor)
else:
return 72
def open_error_message(message = "", title = "Error", icon = "ERROR"):
def draw_error_message(self, context):
self.layout.label(text=message)
bpy.context.window_manager.popup_menu(draw_error_message, title = title, icon = icon)
def get_location_in_current_3d_view(horizontal = "CENTER", vertical = "CENTER", offset = (0, 0), adapt_offset_to_dpi = True):
area = bpy.context.area
if area.type == "VIEW_3D":
for region in area.regions:
if region.type == "WINDOW":
return get_location_in_region(region, horizontal, vertical, offset, adapt_offset_to_dpi)
return Vector((0, 0))
def get_location_in_region(region, horizontal = "CENTER", vertical = "CENTER", offset = (0, 0), adapt_offset_to_dpi = True):
if horizontal == "LEFT": x = 0
elif horizontal == "CENTER": x = region.width / 2
elif horizontal == "RIGHT": x = region.width
else: raise Exception("'{}' is not in ('LEFT', 'CENTER', 'RIGHT')".format(horizontal))
if vertical == "TOP": y = region.height
elif vertical == "CENTER": y = region.height / 2
elif vertical == "BOTTOM": y = 0
else: raise Exception("'{}' is not in ('TOP', 'CENTER', 'BOTTOM')".format(vertical))
offset = Vector(offset)
if adapt_offset_to_dpi: offset *= get_dpi_factor()
return Vector((x, y)) + offset
def get_3d_view_tools_panel_overlay_width(area, placement):
use_region_overlap = bpy.context.preferences.system.use_region_overlap
n = 0
t = 0
if placement == "left":
if use_region_overlap:
for region in area.regions:
if region.type == "UI":
if region.x < bpy.context.region.width/3:
n = region.width
if region.type == "TOOLS":
if region.x < bpy.context.region.width/3:
t = region.width
if placement == "right":
if use_region_overlap:
for region in area.regions:
if region.type == "UI":
if region.x > bpy.context.region.width/3:
n = region.width
if region.type == "TOOLS":
if region.x > bpy.context.region.width/3:
t = region.width
return n + t
def write_text(layout, text, width = 30, icon = "NONE"):
col = layout.column(align = True)
col.scale_y = 0.85
prefix = " "
for paragraph in text.split("\n"):
for line in textwrap.wrap(paragraph, width):
col.label(text=prefix + line, icon = icon)
if icon != "NONE": prefix = " "
icon = "NONE"
mouse_position = Vector((0, 0))
def get_mouse_position_in_current_region():
bpy.ops.hops.store_mouse_position("INVOKE_DEFAULT")
return mouse_position.copy()
class HOPS_OT_StoreMousePosition(bpy.types.Operator):
bl_idname = "hops.store_mouse_position"
bl_label = "Store Mouse Position"
bl_options = {"REGISTER", "INTERNAL"}
def invoke(self, context, event):
mouse_position.x = event.mouse_region_x
mouse_position.y = event.mouse_region_y
return {"FINISHED"}