revamp loading and panels

This commit is contained in:
jrkb 2024-08-26 18:48:43 +02:00
parent 3631ac8e49
commit 97ca4f5d23
4 changed files with 219 additions and 93 deletions

View file

@ -245,6 +245,10 @@ class ABC3D_data(bpy.types.PropertyGroup):
maxlen=1024,
# update=font_path_update_callback,
subtype="FILE_PATH")
export_dir: bpy.props.StringProperty(
name="Export Directory",
description=f"The directory in which we will export fonts.\nIf it is blank, we will export to the addon assets path.\nThis is where the fonts are installed.",
subtype="DIR_PATH")
class ABC3D_UL_fonts(bpy.types.UIList):
@ -278,25 +282,27 @@ 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"
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_data = scene.abc3d_data
abc3d_data = scene.abc3d_data
# layout.row().operator(f"{__name__}.install_font", text='Install new font')
box = layout.box()
box.row().label(text="1. Select fontfile")
box.row().prop(context.scene.abc3d_data, "font_path")
box.row().label(text="2. Install it:")
box.row().operator(f"{__name__}.install_font", text='Install new font')
class ABC3D_PT_FontList(bpy.types.Panel):
@ -477,7 +483,13 @@ class ABC3D_PT_FontCreation(bpy.types.Panel):
abc3d_data = scene.abc3d_data
layout.row().operator(f"{__name__}.create_font_from_objects", text='Create/Extend Font')
layout.row().operator(f"{__name__}.save_font_to_file", text='Save Font To File')
box = layout.box()
box.row().label(text="Exporting a fontfile")
box.row().label(text="1. Select export directory:")
box.prop(abc3d_data, 'export_dir')
box.row().label(text="2. More options and export:")
box.row().operator(f"{__name__}.save_font_to_file", text='Export Font To File')
layout.row().operator(f"{__name__}.toggle_abc3d_collection", text='Toggle Collection')
box = layout.box()
box.label(text="metrics")
@ -594,6 +606,7 @@ class ABC3D_OT_InstallFont(bpy.types.Operator):
abc3d_data = context.scene.abc3d_data
layout = self.layout
# layout.row().prop(self, "font_path") # crashes on Mac OS?
# layout.row().prop(abc3d_data, "font_path") # closes the stupid panel 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,")
@ -742,7 +755,7 @@ class ABC3D_OT_AlignMetrics(bpy.types.Operator):
return {'FINISHED'}
class ABC3D_OT_TemporaryHelper(bpy.types.Operator):
"""Temp Font 3D"""
"""Temporary Helper ABC3D\nThis could do anything.\nIt's just there to make random functions available for testing."""
bl_idname = f"{__name__}.temporaryhelper"
bl_label = "Temp Font"
bl_options = {'REGISTER', 'UNDO'}
@ -848,7 +861,7 @@ class ABC3D_OT_PlaceText(bpy.types.Operator):
text: bpy.props.StringProperty(
name="Text",
description="The text.",
default="HELLO",
default="ABC3D",
maxlen=1024,
)
# target_object: bpy.props.PointerProperty(
@ -891,7 +904,6 @@ class ABC3D_OT_PlaceText(bpy.types.Operator):
global shared
scene = bpy.context.scene
abc3d = scene.abc3d
abc3d_data = scene.abc3d_data
selected = bpy.context.view_layer.objects.active
@ -953,7 +965,7 @@ class ABC3D_OT_ToggleABC3DCollection(bpy.types.Operator):
fontcollection = bpy.data.collections.get("ABC3D")
if fontcollection is None:
self.report({'INFO'}, f"{bl_info['name']}: There is no collection")
self.report({'INFO'}, f"{bl_info['name']}: There is no collection. Did you use or create any glyphs yet?")
elif scene.collection.children.find(fontcollection.name) < 0:
scene.collection.children.link(fontcollection)
self.report({'INFO'}, f"{bl_info['name']}: show collection")
@ -969,30 +981,40 @@ class ABC3D_OT_SaveFontToFile(bpy.types.Operator):
bl_idname = f"{__name__}.save_font_to_file"
bl_label = "Save Font"
bl_options = {'REGISTER', 'UNDO'}
save_path: bpy.props.StringProperty(name="save_path", subtype="DIR_PATH")
def invoke(self, context, event):
wm = context.window_manager
preferences = getPreferences(context)
abc3d_data = context.scene.abc3d_data
if abc3d_data.export_dir == "":
abc3d_data.export_dir = os.path.join(preferences.assets_dir, "fonts")
return wm.invoke_props_dialog(self)
# def draw(self, contex):
# layout = self.layout
# layout.prop(self, 'font_name')
# layout.prop(self, 'face_name')
# layout.prop(self, 'import_infix')
# layout.prop(self, 'fix_common_misspellings')
# for k in Font.known_misspellings:
# character = ""
# if Font.known_misspellings[k] in Font.name_to_glyph_d:
# character = f" ({Font.name_to_glyph_d[Font.known_misspellings[k]]})"
# layout.label(text=f"{k} -> {Font.known_misspellings[k]}{character}")
def draw(self, context):
abc3d_data = context.scene.abc3d_data
layout = self.layout
layout.label(text="Available Fonts")
layout.template_list("ABC3D_UL_fonts", "", abc3d_data, "available_fonts", abc3d_data, "active_font_index")
available_font = abc3d_data.available_fonts[abc3d_data.active_font_index]
font_name = available_font.font_name
face_name = available_font.face_name
loaded_glyphs = sorted(Font.fonts[font_name].faces[face_name].loaded_glyphs)
n = 16
n_rows = int(len(loaded_glyphs) / n)
box = layout.box()
box.row().label(text=f"Glyphs to be exported:")
subbox = box.box()
for i in range(0, n_rows + 1):
text = ''.join([f"{u}" for ui, u in enumerate(loaded_glyphs) if ui < (i+1) * n and ui >= i * n])
scale_y = 0.5
row = subbox.row(); row.scale_y = scale_y
row.label(text=text)
layout.prop(abc3d_data, 'export_dir')
def execute(self, context):
global shared
scene = bpy.context.scene
abc3d_data = scene.abc3d_data
abc3d = scene.abc3d
fontcollection = bpy.data.collections.get("ABC3D")
@ -1049,7 +1071,7 @@ class ABC3D_OT_SaveFontToFile(bpy.types.Operator):
context_override["selected_objects"] = list(export_objects)
# context_override["scene"] = bpy.context.scene.copy()
with bpy.context.temp_override(**context_override):
filepath = f"{preferences.assets_dir}/fonts/{selected_font.font_name}.gltf"
filepath = f"{abc3d_data.export_dir}/{selected_font.font_name}.glb"
# get rid of scene extra data before export
scene_keys = []
for k in bpy.context.scene.keys():
@ -1061,22 +1083,22 @@ class ABC3D_OT_SaveFontToFile(bpy.types.Operator):
bpy.ops.export_scene.gltf(
filepath=filepath,
check_existing=False,
export_format='GLB', # GLB or GLTF_SEPARATE
export_format='GLB', # GLB or GLTF_SEPARATE (also change filepath)
export_extras=True,
# export_hierarchy_full_collections=True,
# use_active_collection_with_nested=True,
use_selection=True,
use_active_scene=True,
)
# bpy.app.timers.register(lambda: bpy.ops.scene.delete(), first_interval=5)
bpy.app.timers.register(lambda: bpy.ops.scene.delete(), first_interval=1)
bpy.ops.scene.delete()
# bpy.ops.scene.delete()
# restore()
for obj in fontcollection.objects:
if obj["font_name"] == selected_font.font_name:
if butils.is_metrics_object(obj):
butils.remove_faces_from_metrics(obj)
def remove_faces():
for obj in fontcollection.objects:
if obj["font_name"] == selected_font.font_name:
if butils.is_metrics_object(obj):
butils.remove_faces_from_metrics(obj)
bpy.app.timers.register(lambda: remove_faces(), first_interval=2)
self.report({'INFO'}, f"did it")
return {'FINISHED'}
@ -1111,55 +1133,61 @@ class ABC3D_OT_CreateFontFromObjects(bpy.types.Operator):
wm = context.window_manager
return wm.invoke_props_dialog(self)
def draw(self, contex):
def draw(self, context):
layout = self.layout
row = layout.row()
row.prop(self, 'autodetect_names')
if self.autodetect_names:
scale_y = 0.5
row = layout.row(); row.scale_y = scale_y
row.label(text="Watch out, follow convention in naming your meshes:")
row = layout.row(); row.scale_y = scale_y
row.label(text="'<glyph id>_<font name>_<face name>'")
row = layout.row(); row.scale_y = scale_y
row.label(text=" - glyph id: unicode glyph name or raw glyph")
row = layout.row(); row.scale_y = scale_y
row.label(text=" - font name: font name with underscore")
row = layout.row(); row.scale_y = scale_y
row.label(text=" - face name: face name")
row = layout.row(); row.scale_y = scale_y
row.label(text="working examples:")
row = layout.row(); row.scale_y = scale_y
row.label(text="- 'A_NM_Origin_Tender'")
row = layout.row(); row.scale_y = scale_y
row.label(text="- 'B_NM_Origin_Tender'")
row = layout.row(); row.scale_y = scale_y
row.label(text="- 'arrowright_NM_Origin_Tender'")
row = layout.row(); row.scale_y = scale_y
row.label(text="- '→_NM_Origin_Tender' (equal to above)")
row = layout.row(); row.scale_y = scale_y
row.label(text="- 'quotesingle_NM_Origin_Tender.001'")
row = layout.row(); row.scale_y = scale_y
row.label(text="- 'colon_NM_Origin_Tender_2'")
box = layout.box()
box.enabled = not self.autodetect_names
box.prop(self, 'font_name')
box.prop(self, 'face_name')
box.prop(self, 'import_infix')
layout.prop(self, 'fix_common_misspellings')
if self.fix_common_misspellings:
for k in Font.known_misspellings:
character = ""
if Font.known_misspellings[k] in Font.name_to_glyph_d:
character = f" ({Font.name_to_glyph_d[Font.known_misspellings[k]]})"
row = layout.row(); row.scale_y = 0.5
row.label(text=f"{k}{Font.known_misspellings[k]}{character}")
if len(context.selected_objects) == 0:
layout.row().label(text="No objects selected.", icon="ERROR")
layout.row().label(text="Please select your glyphs first.", icon="INFO")
else:
row = layout.row()
row.prop(self, 'autodetect_names')
if self.autodetect_names:
scale_y = 0.5
row = layout.row(); row.scale_y = scale_y
row.label(text="Watch out, follow convention in naming your meshes:")
row = layout.row(); row.scale_y = scale_y
row.label(text="'<glyph id>_<font name>_<face name>'")
row = layout.row(); row.scale_y = scale_y
row.label(text=" - glyph id: unicode glyph name or raw glyph")
row = layout.row(); row.scale_y = scale_y
row.label(text=" - font name: font name with underscore")
row = layout.row(); row.scale_y = scale_y
row.label(text=" - face name: face name")
row = layout.row(); row.scale_y = scale_y
row.label(text="working examples:")
row = layout.row(); row.scale_y = scale_y
row.label(text="- 'A_NM_Origin_Tender'")
row = layout.row(); row.scale_y = scale_y
row.label(text="- 'B_NM_Origin_Tender'")
row = layout.row(); row.scale_y = scale_y
row.label(text="- 'arrowright_NM_Origin_Tender'")
row = layout.row(); row.scale_y = scale_y
row.label(text="- '→_NM_Origin_Tender' (equal to above)")
row = layout.row(); row.scale_y = scale_y
row.label(text="- 'quotesingle_NM_Origin_Tender.001'")
row = layout.row(); row.scale_y = scale_y
row.label(text="- 'colon_NM_Origin_Tender_2'")
box = layout.box()
box.enabled = not self.autodetect_names
box.prop(self, 'font_name')
box.prop(self, 'face_name')
box.prop(self, 'import_infix')
layout.prop(self, 'fix_common_misspellings')
if self.fix_common_misspellings:
for k in Font.known_misspellings:
character = ""
if Font.known_misspellings[k] in Font.name_to_glyph_d:
character = f" ({Font.name_to_glyph_d[Font.known_misspellings[k]]})"
row = layout.row(); row.scale_y = 0.5
row.label(text=f"{k}{Font.known_misspellings[k]}{character}")
def execute(self, context):
print(f"executing {self.bl_idname}")
if len(context.selected_objects) == 0:
print(f"cancelled {self.bl_idname} - no objects selected")
return {'CANCELLED'}
global shared
scene = bpy.context.scene
abc3d = scene.abc3d
abc3d_data = scene.abc3d_data
fontcollection = bpy.data.collections.get("ABC3D")
@ -1250,7 +1278,6 @@ class ABC3D_PT_RightPropertiesPanel(bpy.types.Panel):
def draw(self, context):
layout = self.layout
scene = context.scene
abc3d = scene.abc3d
abc3d_data = scene.abc3d_data
obj = context.active_object
@ -1304,7 +1331,6 @@ class ABC3D_OT_Reporter(bpy.types.Operator):
def execute(self, context):
#this is where I send the message
self.report({'INFO'}, 'whatever')
print("lalala reporter")
for i in range(0,10):
butils.ShowMessageBox('whatever','INFO','INFO')
return {'FINISHED'}
@ -1320,7 +1346,7 @@ classes = (
ABC3D_UL_fonts,
ABC3D_UL_texts,
ABC3D_PT_Panel,
# ABC3D_PT_LoadFontPanel,
ABC3D_PT_LoadFontPanel,
ABC3D_PT_FontList,
ABC3D_PT_TextPlacement,
ABC3D_PT_TextManagement,
@ -1342,6 +1368,37 @@ classes = (
ABC3D_OT_Reporter,
)
def compare_text_object_with_object(t, o, strict=False):
for k in o.keys():
if k == f"{utils.prefix()}_type":
if o[k] != "textobject":
return False
elif k.startswith(f"{utils.prefix()}_"):
p = k.replace(f"{utils.prefix()}_","")
if p in t.keys():
if t[p] != o[k]:
return False
else:
print(f"{__name__} set_text_object: did not find key ({p})")
if strict:
return False
# for p in t.keys():
# if
return True
def detect_text():
scene = bpy.context.scene
abc3d_data = scene.abc3d_data
for o in scene.objects:
if o[f"{utils.prefix()}_type"] == "textobject":
linked_textobject = int(o[f"{utils.prefix()}_linked_textobject"])
if len(abc3d_data.available_texts) > linked_textobject \
and abc3d_data.available_texts[linked_textobject].text_object == o:
t = abc3d_data.available_texts[linked_textobject]
a = test_availability(o["font_name"], o["face_name"], o["text"])
butils.transfer_blender_object_to_text_properties(o, t)
@persistent
def load_handler(self, dummy):
if not bpy.app.timers.is_registered(butils.execute_queued_functions):