font path adventures with Mac OS
This commit is contained in:
parent
edb2c8cb8b
commit
3631ac8e49
2 changed files with 71 additions and 89 deletions
158
__init__.py
158
__init__.py
|
@ -93,60 +93,11 @@ class ABC3D_addonPreferences(bpy.types.AddonPreferences):
|
|||
layout.prop(self, "assets_dir")
|
||||
|
||||
|
||||
class ABC3D_settings(bpy.types.PropertyGroup):
|
||||
font_path: bpy.props.StringProperty(
|
||||
name="Font path",
|
||||
description="Load a *.glb or *.gltf fontfile from disk",
|
||||
default="",
|
||||
maxlen=1024,
|
||||
subtype="FILE_PATH")
|
||||
import_infix: bpy.props.StringProperty(
|
||||
name="Font name import infix",
|
||||
description="The infix which all font objects to import have. obj name: 'A_NM_Origin_Tender' -> infix: '_NM_Origin_Tender'",
|
||||
default="_NM_",
|
||||
maxlen=1024,
|
||||
)
|
||||
text: bpy.props.StringProperty(
|
||||
name="Text",
|
||||
description="The text.",
|
||||
default="HELLO",
|
||||
maxlen=1024,
|
||||
)
|
||||
target_object: bpy.props.PointerProperty(
|
||||
name="The Target Object",
|
||||
description="The target, which will be populated by character children of text.",
|
||||
type=bpy.types.Object,
|
||||
)
|
||||
letter_spacing: bpy.props.FloatProperty(
|
||||
name="Letter Spacing",
|
||||
description="Letter Spacing",
|
||||
default=0.0,
|
||||
)
|
||||
font_size: bpy.props.FloatProperty(
|
||||
name="Font Size",
|
||||
default=1.0,
|
||||
subtype='NONE',
|
||||
)
|
||||
translation: bpy.props.FloatVectorProperty(
|
||||
name="Translation",
|
||||
default=(0.0, 0.0, 0.0),
|
||||
subtype='TRANSLATION',
|
||||
)
|
||||
orientation: bpy.props.FloatVectorProperty(
|
||||
name="Orientation",
|
||||
default=(1.5707963267948966, 0.0, 0.0), # 90 degrees in radians
|
||||
subtype='EULER',
|
||||
)
|
||||
offset: bpy.props.FloatProperty(
|
||||
name="Offset",
|
||||
default=0.0,
|
||||
subtype='NONE',
|
||||
)
|
||||
|
||||
class ABC3D_available_font(bpy.types.PropertyGroup):
|
||||
font_name: bpy.props.StringProperty(name="")
|
||||
face_name: bpy.props.StringProperty(name="")
|
||||
|
||||
|
||||
class ABC3D_glyph_properties(bpy.types.PropertyGroup):
|
||||
glyph_id: bpy.props.StringProperty(maxlen=1)
|
||||
glyph_object: bpy.props.PointerProperty(type=bpy.types.Object)
|
||||
|
@ -282,6 +233,20 @@ class ABC3D_data(bpy.types.PropertyGroup):
|
|||
|
||||
active_text_index: bpy.props.IntProperty(update=active_text_index_update)
|
||||
|
||||
# def font_path_update_callback(self, context):
|
||||
# butils.ShowMessageBox("Friendly Reminder", message="do not forget to click on 'Install new font'")
|
||||
# bpy.ops.abc3d.install_font()
|
||||
|
||||
# stupid hack for Mac OS
|
||||
font_path: bpy.props.StringProperty(
|
||||
name="Font path",
|
||||
description="Install a *.glb or *.gltf fontfile from disk",
|
||||
default="",
|
||||
maxlen=1024,
|
||||
# update=font_path_update_callback,
|
||||
subtype="FILE_PATH")
|
||||
|
||||
|
||||
class ABC3D_UL_fonts(bpy.types.UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
layout.label(text=f"{index}: {item.font_name} {item.face_name}") # avoids renaming the item by accident
|
||||
|
@ -313,27 +278,25 @@ class ABC3D_PT_Panel(bpy.types.Panel):
|
|||
layout.row().label(text='no fonts loaded yet')
|
||||
|
||||
layout.operator(f"{__name__}.load_installed_fonts", text="load installed fonts", icon=icon)
|
||||
layout.row().prop(context.scene.abc3d_data, "font_path")
|
||||
layout.row().operator(f"{__name__}.install_font", text='Install new font')
|
||||
|
||||
|
||||
class ABC3D_PT_LoadFontPanel(bpy.types.Panel):
|
||||
bl_label = "Install a new font"
|
||||
bl_parent_id = "ABC3D_PT_Panel"
|
||||
bl_category = "ABC3D"
|
||||
bl_space_type = "VIEW_3D"
|
||||
bl_region_type = "UI"
|
||||
bl_options = {"DEFAULT_CLOSED"}
|
||||
# class ABC3D_PT_LoadFontPanel(bpy.types.Panel):
|
||||
# bl_label = "Install a new font"
|
||||
# bl_parent_id = "ABC3D_PT_Panel"
|
||||
# bl_category = "ABC3D"
|
||||
# bl_space_type = "VIEW_3D"
|
||||
# bl_region_type = "UI"
|
||||
|
||||
def draw(self, context):
|
||||
layout = self.layout
|
||||
wm = context.window_manager
|
||||
scene = context.scene
|
||||
# def draw(self, context):
|
||||
# layout = self.layout
|
||||
# wm = context.window_manager
|
||||
# scene = context.scene
|
||||
|
||||
abc3d = scene.abc3d
|
||||
abc3d_data = scene.abc3d_data
|
||||
# abc3d_data = scene.abc3d_data
|
||||
|
||||
layout.label(text="Install FontFile:")
|
||||
layout.row().prop(abc3d, "font_path")
|
||||
layout.row().operator(f"{__name__}.install_font", text='Install')
|
||||
# layout.row().operator(f"{__name__}.install_font", text='Install new font')
|
||||
|
||||
|
||||
class ABC3D_PT_FontList(bpy.types.Panel):
|
||||
|
@ -348,7 +311,6 @@ class ABC3D_PT_FontList(bpy.types.Panel):
|
|||
wm = context.window_manager
|
||||
scene = context.scene
|
||||
|
||||
abc3d = scene.abc3d
|
||||
abc3d_data = scene.abc3d_data
|
||||
|
||||
layout.label(text="Available Fonts")
|
||||
|
@ -403,7 +365,6 @@ class ABC3D_PT_TextPlacement(bpy.types.Panel):
|
|||
wm = context.window_manager
|
||||
scene = context.scene
|
||||
|
||||
abc3d = scene.abc3d
|
||||
abc3d_data = scene.abc3d_data
|
||||
|
||||
placerow = layout.row()
|
||||
|
@ -425,7 +386,6 @@ class ABC3D_PT_TextManagement(bpy.types.Panel):
|
|||
@classmethod
|
||||
def poll(self, context):
|
||||
scene = context.scene
|
||||
abc3d = scene.abc3d
|
||||
abc3d_data = scene.abc3d_data
|
||||
# TODO: update available_texts
|
||||
def update():
|
||||
|
@ -495,7 +455,6 @@ class ABC3D_PT_TextManagement(bpy.types.Panel):
|
|||
wm = context.window_manager
|
||||
scene = context.scene
|
||||
|
||||
abc3d = scene.abc3d
|
||||
abc3d_data = scene.abc3d_data
|
||||
|
||||
layout.label(text="Text Objects")
|
||||
|
@ -515,7 +474,6 @@ class ABC3D_PT_FontCreation(bpy.types.Panel):
|
|||
wm = context.window_manager
|
||||
scene = context.scene
|
||||
|
||||
abc3d = scene.abc3d
|
||||
abc3d_data = scene.abc3d_data
|
||||
|
||||
layout.row().operator(f"{__name__}.create_font_from_objects", text='Create/Extend Font')
|
||||
|
@ -580,7 +538,6 @@ class ABC3D_PT_TextPropertiesPanel(bpy.types.Panel):
|
|||
layout = self.layout
|
||||
wm = context.window_manager
|
||||
scene = context.scene
|
||||
abc3d = scene.abc3d
|
||||
abc3d_data = scene.abc3d_data
|
||||
|
||||
props = self.get_active_text_properties()
|
||||
|
@ -609,6 +566,20 @@ class ABC3D_OT_InstallFont(bpy.types.Operator):
|
|||
bl_label = "Load Font"
|
||||
bl_options = {'REGISTER', 'UNDO'}
|
||||
|
||||
def font_path_update_callback(self, context):
|
||||
if os.path.exists(self.font_path):
|
||||
print(f"{self.font_path} does exist")
|
||||
else:
|
||||
print(f"{self.font_path} does not exist")
|
||||
|
||||
font_path: bpy.props.StringProperty(
|
||||
name="Font path",
|
||||
description="Install a *.glb or *.gltf fontfile from disk",
|
||||
default="",
|
||||
maxlen=1024,
|
||||
# update=font_path_update_callback,
|
||||
subtype="FILE_PATH")
|
||||
|
||||
install_in_assets: bpy.props.BoolProperty(
|
||||
name="install in assets",
|
||||
description="install the font in the assets directory of the addon",
|
||||
|
@ -620,7 +591,9 @@ class ABC3D_OT_InstallFont(bpy.types.Operator):
|
|||
default=False)
|
||||
|
||||
def draw(self, context):
|
||||
abc3d_data = context.scene.abc3d_data
|
||||
layout = self.layout
|
||||
# layout.row().prop(self, "font_path") # crashes on Mac OS?
|
||||
layout.row().prop(self, "install_in_assets")
|
||||
if not self.install_in_assets and not self.load_into_memory:
|
||||
layout.label(text="If the fontfile is not installed,")
|
||||
|
@ -634,27 +607,42 @@ class ABC3D_OT_InstallFont(bpy.types.Operator):
|
|||
layout.label(text="load the font data on demand.")
|
||||
|
||||
def invoke(self, context, event):
|
||||
abc3d_data = context.scene.abc3d_data
|
||||
self.font_path = abc3d_data.font_path
|
||||
if not os.path.exists(self.font_path):
|
||||
bpy.app.timers.register(lambda: butils.ShowMessageBox(
|
||||
title=f"{__name__} Warning",
|
||||
icon="ERROR",
|
||||
message=[
|
||||
f"We believe the font path ({self.font_path}) does not exist.",
|
||||
f"Did you select your fontfile in the field above the 'Install new font'-button?",
|
||||
],
|
||||
), first_interval=0.1)
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
|
||||
def execute(self, context):
|
||||
scene = bpy.context.scene
|
||||
|
||||
if not os.path.exists(scene.abc3d.font_path):
|
||||
abc3d_data = context.scene.abc3d_data
|
||||
if not os.path.exists(self.font_path):
|
||||
butils.ShowMessageBox(
|
||||
title=f"{__name__} Warning",
|
||||
icon="ERROR",
|
||||
message=f"We believe the font path ({scene.abc3d.font_path}) does not exist.",
|
||||
message=[
|
||||
f"Could not install font.",
|
||||
f"We believe the font path ({self.font_path}) does not exist.",
|
||||
f"If this is an error, please let us know.",
|
||||
],
|
||||
)
|
||||
return {'CANCELLED'}
|
||||
|
||||
if self.install_in_assets:
|
||||
preferences = getPreferences(context)
|
||||
filename = os.path.basename(scene.abc3d.font_path)
|
||||
filename = os.path.basename(self.font_path)
|
||||
target = os.path.join(preferences.assets_dir, "fonts", filename)
|
||||
print(f"installing {scene.abc3d.font_path} -> {target}")
|
||||
import shutil
|
||||
os.makedirs(os.path.dirname(target), exist_ok=True)
|
||||
shutil.copyfile(scene.abc3d.font_path, target)
|
||||
shutil.copyfile(self.font_path, target)
|
||||
# def register_load(target, load=False):
|
||||
# print(f"registering installed fonts")
|
||||
# bpy.app.timers.register(lambda: register_load(target, self.load_into_memory), first_interval=5)
|
||||
|
@ -663,9 +651,9 @@ class ABC3D_OT_InstallFont(bpy.types.Operator):
|
|||
butils.load_font_from_filepath(target)
|
||||
butils.update_available_fonts()
|
||||
else:
|
||||
butils.register_font_from_filepath(scene.abc3d.font_path)
|
||||
butils.register_font_from_filepath(self.font_path)
|
||||
if self.load_into_memory:
|
||||
butils.load_font_from_filepath(scene.abc3d.font_path)
|
||||
butils.load_font_from_filepath(self.font_path)
|
||||
|
||||
return {'FINISHED'}
|
||||
|
||||
|
@ -692,6 +680,7 @@ class ABC3D_OT_LoadInstalledFonts(bpy.types.Operator):
|
|||
return context.window_manager.invoke_props_dialog(self)
|
||||
|
||||
def execute(self, context):
|
||||
print("EXECUTE LOAD INSTALLED FONTS")
|
||||
scene = bpy.context.scene
|
||||
|
||||
if self.load_into_memory:
|
||||
|
@ -907,9 +896,6 @@ class ABC3D_OT_PlaceText(bpy.types.Operator):
|
|||
|
||||
selected = bpy.context.view_layer.objects.active
|
||||
|
||||
# if abc3d.target_object:
|
||||
# selected = abc3d.target_object
|
||||
|
||||
if selected:
|
||||
# font = abc3d_data.available_fonts[abc3d_data.active_font_index]
|
||||
# font_name = font.font_name
|
||||
|
@ -1181,7 +1167,7 @@ class ABC3D_OT_CreateFontFromObjects(bpy.types.Operator):
|
|||
if fontcollection is None:
|
||||
fontcollection = bpy.data.collections.new("ABC3D")
|
||||
|
||||
ifxsplit = abc3d.import_infix.split('_')
|
||||
ifxsplit = self.import_infix.split('_')
|
||||
# if len(ifxsplit) != 4:
|
||||
|
||||
# font_name = f"{ifxsplit[1]}_{ifxsplit[2]}"
|
||||
|
@ -1207,7 +1193,6 @@ class ABC3D_OT_CreateFontFromObjects(bpy.types.Operator):
|
|||
|
||||
if butils.is_mesh(o) and not butils.is_metrics_object(o):
|
||||
uc = o.users_collection
|
||||
# regex = f"{abc3d.import_infix}(.)*"
|
||||
if self.fix_common_misspellings:
|
||||
o.name = Font.fix_glyph_name_misspellings(o.name)
|
||||
# name = re.sub(regex, "", o.name)
|
||||
|
@ -1332,11 +1317,10 @@ classes = (
|
|||
ABC3D_glyph_properties,
|
||||
ABC3D_text_properties,
|
||||
ABC3D_data,
|
||||
ABC3D_settings,
|
||||
ABC3D_UL_fonts,
|
||||
ABC3D_UL_texts,
|
||||
ABC3D_PT_Panel,
|
||||
ABC3D_PT_LoadFontPanel,
|
||||
# ABC3D_PT_LoadFontPanel,
|
||||
ABC3D_PT_FontList,
|
||||
ABC3D_PT_TextPlacement,
|
||||
ABC3D_PT_TextManagement,
|
||||
|
@ -1378,7 +1362,6 @@ def on_frame_changed(self, dummy):
|
|||
def register():
|
||||
for cls in classes:
|
||||
bpy.utils.register_class(cls)
|
||||
bpy.types.Scene.abc3d = bpy.props.PointerProperty(type=ABC3D_settings)
|
||||
bpy.types.Scene.abc3d_data = bpy.props.PointerProperty(type=ABC3D_data)
|
||||
# bpy.types.Object.__del__ = lambda self: print(f"Bye {self.name}")
|
||||
print(f"REGISTER {bl_info['name']}")
|
||||
|
@ -1413,7 +1396,6 @@ def unregister():
|
|||
if on_frame_changed in bpy.app.handlers.frame_change_post:
|
||||
bpy.app.handlers.frame_change_post.remove(on_frame_changed)
|
||||
|
||||
del bpy.types.Scene.abc3d
|
||||
del bpy.types.Scene.abc3d_data
|
||||
print(f"UNREGISTER {bl_info['name']}")
|
||||
|
||||
|
|
|
@ -416,7 +416,7 @@ def register_font_from_filepath(filepath):
|
|||
|
||||
def load_font_from_filepath(filepath, glyphs="", font_name="", face_name=""):
|
||||
if not filepath.endswith(".glb") and not filepath.endswith(".gltf"):
|
||||
ShowMessageBox(f"{bl_info['name']} Font loading error", 'ERROR', f"Filepath({filepath}) is not a *.glb or *.gltf file")
|
||||
ShowMessageBox(f"Font loading error", 'ERROR', f"Filepath({filepath}) is not a *.glb or *.gltf file")
|
||||
return False
|
||||
|
||||
marker_property = "font_import"
|
||||
|
|
Loading…
Reference in a new issue