Files
blender-portable-repo/scripts/addons/blender_visual_scripting_addon/utils.py
T
2026-03-17 14:30:01 -06:00

107 lines
3.0 KiB
Python

import bpy
import re
def get_python_name(name, replacement="", separator="_", lower=True):
""" Returns the given name as a valid python represention to use as variable names in scripts """
# format string
name = name.replace(" ", separator)
if lower:
name = name.lower()
# Remove invalid characters
name = re.sub('[^0-9a-zA-Z_]', '', name)
# Remove leading characters until we find a letter or underscore
name = re.sub('^[^a-zA-Z]+', '', name)
# return string
if not name:
return replacement
return name
def unique_collection_name(name, default, name_list, separator="", includes_name=False):
""" Returns a unique name based for the given list of names """
if not name:
name = default
if name in name_list and includes_name:
name_list.remove(name)
if name in name_list:
number = 1
if len(name) > 3 and name[-3:].isdigit() and name[-4] == separator:
name = name[:-4]
while f"{name}{separator}{str(number).zfill(3)}" in name_list:
number += 1
name = f"{name}{separator}{str(number).zfill(3)}"
return name
def get_indents(line):
""" Returns the amount of spaces at the start of the given line """
return len(line) - len(line.lstrip())
def get_min_indent(code_lines):
""" Returns the minimum indent of the given lines of text """
min_indent = 9999
for line in code_lines:
if not line.isspace() and line:
min_indent = min(min_indent, get_indents(line))
return min_indent if min_indent != 9999 else 0
def normalize_code(raw_code):
""" Normalizes the given code to the minimum indent and removes empty lines """
lines = raw_code.split("\n")
min_indent = get_min_indent(lines)
indented = []
for line in lines:
new_line = line[min_indent:]
if new_line:
indented.append(new_line)
return "\n".join(indented)
def indent_code(code, indents, start_line_index=1):
""" Indents the given code by the given amount of indents. Use this when inserting multiline blocks into code """
# join code blocks if given
if type(code) == list:
code = "\n".join(code)
# split code and indent properly
lines = code.split("\n")
for i in range(start_line_index, len(lines)):
lines[i] = " "*(4*indents) + lines[i]
return "\n".join(lines)
class SN_OT_Tooltip(bpy.types.Operator):
bl_idname = "sn.tooltip"
bl_label = "Tooltip"
bl_description = "Click to learn more"
bl_options = {"REGISTER", "INTERNAL"}
text: bpy.props.StringProperty(options={"HIDDEN", "SKIP_SAVE"})
def execute(self, context):
return {"FINISHED"}
def draw(self, context):
layout = self.layout
row = layout.row()
row.enabled = False
row.label(text="Info")
col = layout.column(align=True)
for line in self.text.split("\n"):
col.label(text=line)
def invoke(self, context, event):
return context.window_manager.invoke_popup(self, width=500)