Skip to content

Commit b4d9efb

Browse files
committed
use textbox instead of editor
1 parent f00311e commit b4d9efb

2 files changed

Lines changed: 70 additions & 112 deletions

File tree

typst_importer/__init__.py

Lines changed: 41 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,10 @@
3939
OBJECT_OT_copy_without_keyframes,
4040
)
4141

42-
from .operators.text_editor_import import (
43-
ImportFromTextEditorAsCurveOperator,
44-
ImportFromTextEditorAsMeshOperator,
45-
ImportFromTextEditorAsUnfilledCurveOperator,
42+
from .operators.textbox_import import (
43+
ImportFromTextboxAsCurveOperator,
44+
ImportFromTextboxAsMeshOperator,
45+
ImportFromTextboxAsUnfilledCurveOperator,
4646
)
4747

4848
from .operators.export_svg import (
@@ -55,10 +55,10 @@
5555
addon_keymaps = []
5656

5757

58-
# Property to store selected text editor document
59-
bpy.types.WindowManager.typst_selected_text = bpy.props.StringProperty(
60-
name="Selected Text",
61-
description="Selected text document from Blender's text editor",
58+
# Property to store the Typst content entered in the textbox
59+
bpy.types.Scene.typst_text = bpy.props.StringProperty(
60+
name="Typst Text",
61+
description="Typst content to import",
6262
default="",
6363
)
6464

@@ -85,81 +85,58 @@
8585
)
8686

8787

88-
# Panel for text editor import
89-
class VIEW3D_PT_typst_text_editor_import(bpy.types.Panel):
88+
# Panel for textbox import
89+
class VIEW3D_PT_typst_textbox_import(bpy.types.Panel):
9090
bl_space_type = "VIEW_3D"
9191
bl_region_type = "UI"
9292
bl_category = "Typst Tools"
93-
bl_label = "Text Editor Import"
93+
bl_label = "Typst Input"
9494

9595
def draw(self, context):
9696
layout = self.layout
9797
wm = context.window_manager
98-
99-
# Get available text documents
100-
text_docs = list(bpy.data.texts.keys())
101-
102-
if not text_docs:
103-
layout.label(text="No text documents found", icon="INFO")
104-
layout.label(text="Create one in the Text Editor")
105-
return
106-
107-
# Text document selector
98+
scene = context.scene
99+
100+
# Multi-line textbox for Typst content
108101
box = layout.box()
109-
box.label(text="Select Text Document")
110-
box.prop_search(
111-
wm,
112-
"typst_selected_text",
113-
bpy.data,
114-
"texts",
115-
text="Document",
116-
icon="TEXT",
117-
)
118-
119-
# Show selected text name or placeholder
120-
selected_text = wm.typst_selected_text
121-
if not selected_text:
122-
box.label(text="No document selected", icon="INFO")
123-
else:
124-
box.label(text=f"Selected: {selected_text}", icon="FILE_TEXT")
125-
102+
box.label(text="Typst Content")
103+
box.textbox(scene, "typst_text")
104+
126105
# Import options
127106
box = layout.box()
128107
box.label(text="Import Options")
129-
108+
130109
# Origin to character option
131110
box.prop(wm, "typst_origin_to_char", text="Origin to Character")
132-
111+
133112
# Custom header option
134113
box.prop(wm, "typst_use_custom_header", text="Use Custom Header")
135-
136-
# Disable buttons if no text is selected
114+
115+
# Disable buttons if the textbox is empty
116+
has_content = bool(scene.typst_text.strip())
137117
row = box.row()
138-
op = row.operator(
139-
ImportFromTextEditorAsUnfilledCurveOperator.bl_idname,
118+
row.operator(
119+
ImportFromTextboxAsUnfilledCurveOperator.bl_idname,
140120
text="Import as Unfilled Curve",
141121
icon="CURVE_BEZCURVE",
142122
)
143-
op.text_name = selected_text
144-
row.enabled = bool(selected_text)
145-
123+
row.enabled = has_content
124+
146125
row = box.row()
147-
op = row.operator(
148-
ImportFromTextEditorAsCurveOperator.bl_idname,
126+
row.operator(
127+
ImportFromTextboxAsCurveOperator.bl_idname,
149128
text="Import as Curve",
150129
icon="CURVE_DATA",
151130
)
152-
op.text_name = selected_text
153-
row.enabled = bool(selected_text)
154-
131+
row.enabled = has_content
132+
155133
row = box.row()
156-
op = row.operator(
157-
ImportFromTextEditorAsMeshOperator.bl_idname,
134+
row.operator(
135+
ImportFromTextboxAsMeshOperator.bl_idname,
158136
text="Import as Mesh",
159137
icon="MESH_DATA",
160138
)
161-
op.text_name = selected_text
162-
row.enabled = bool(selected_text)
139+
row.enabled = has_content
163140

164141

165142
# Panel for the N-panel sidebar
@@ -305,10 +282,10 @@ def register():
305282
bpy.utils.register_class(VIEW3D_PT_typst_animation_tools)
306283
bpy.utils.register_class(OBJECT_OT_join_to_plane)
307284
bpy.utils.register_class(OBJECT_OT_copy_to_plane)
308-
bpy.utils.register_class(ImportFromTextEditorAsCurveOperator)
309-
bpy.utils.register_class(ImportFromTextEditorAsMeshOperator)
310-
bpy.utils.register_class(ImportFromTextEditorAsUnfilledCurveOperator)
311-
bpy.utils.register_class(VIEW3D_PT_typst_text_editor_import)
285+
bpy.utils.register_class(ImportFromTextboxAsCurveOperator)
286+
bpy.utils.register_class(ImportFromTextboxAsMeshOperator)
287+
bpy.utils.register_class(ImportFromTextboxAsUnfilledCurveOperator)
288+
bpy.utils.register_class(VIEW3D_PT_typst_textbox_import)
312289
bpy.utils.register_class(ExportTypstSvgOperator)
313290
bpy.utils.register_class(VIEW3D_PT_typst_export)
314291

@@ -339,10 +316,10 @@ def unregister():
339316
# Unregister Blender classes in reverse order
340317
bpy.utils.unregister_class(VIEW3D_PT_typst_export)
341318
bpy.utils.unregister_class(ExportTypstSvgOperator)
342-
bpy.utils.unregister_class(VIEW3D_PT_typst_text_editor_import)
343-
bpy.utils.unregister_class(ImportFromTextEditorAsUnfilledCurveOperator)
344-
bpy.utils.unregister_class(ImportFromTextEditorAsMeshOperator)
345-
bpy.utils.unregister_class(ImportFromTextEditorAsCurveOperator)
319+
bpy.utils.unregister_class(VIEW3D_PT_typst_textbox_import)
320+
bpy.utils.unregister_class(ImportFromTextboxAsUnfilledCurveOperator)
321+
bpy.utils.unregister_class(ImportFromTextboxAsMeshOperator)
322+
bpy.utils.unregister_class(ImportFromTextboxAsCurveOperator)
346323
bpy.utils.unregister_class(OBJECT_OT_copy_to_plane)
347324
bpy.utils.unregister_class(OBJECT_OT_join_to_plane)
348325
bpy.utils.unregister_class(VIEW3D_PT_typst_animation_tools)
Lines changed: 29 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,27 @@
11
import bpy
2-
from bpy.props import StringProperty
32
from pathlib import Path
43
import tempfile
54
import time
65

76
from ..typst_to_svg import typst_to_blender_curves
87

98

10-
class ImportFromTextEditorOperator(bpy.types.Operator):
11-
"""Base operator for importing from text editor"""
9+
class ImportFromTextboxOperator(bpy.types.Operator):
10+
"""Base operator for importing from the textbox"""
1211
bl_options = {"REGISTER", "UNDO"}
13-
14-
text_name: StringProperty(
15-
name="Text Name",
16-
description="Name of the text document in Blender's text editor",
17-
)
18-
12+
1913
def execute(self, context):
20-
# Get the text data block
21-
text_data = bpy.data.texts.get(self.text_name)
22-
if not text_data:
23-
self.report({"ERROR"}, f"Text document '{self.text_name}' not found")
24-
return {"CANCELLED"}
25-
26-
# Get the text content
27-
text_content = text_data.as_string()
14+
# Get the textbox content
15+
text_content = context.scene.typst_text
2816
if not text_content.strip():
29-
self.report({"WARNING"}, f"Text document '{self.text_name}' is empty")
17+
self.report({"WARNING"}, "Textbox is empty")
3018
return {"CANCELLED"}
31-
19+
3220
# Get options from window manager
3321
wm = context.window_manager
3422
use_custom_header = getattr(wm, "typst_use_custom_header", False)
3523
origin_to_char = getattr(wm, "typst_origin_to_char", False)
36-
24+
3725
# Apply custom header if checkbox is checked
3826
if use_custom_header:
3927
default_header = """#set page(width: auto, height: auto, margin: 0cm, fill: none)
@@ -42,28 +30,22 @@ def execute(self, context):
4230
final_content = default_header + text_content
4331
else:
4432
final_content = text_content
45-
46-
# Determine file extension based on text name or default to .txt
47-
if self.text_name.lower().endswith(('.txt', '.typ')):
48-
ext = Path(self.text_name).suffix
49-
else:
50-
ext = '.txt'
51-
33+
5234
# Write content to temporary file
5335
temp_dir = Path(tempfile.gettempdir())
54-
temp_file = temp_dir / f"{self.text_name}{ext}"
36+
temp_file = temp_dir / "typst_textbox.txt"
5537
temp_file.write_text(final_content)
56-
38+
5739
# Start timer
5840
start_time = time.perf_counter()
59-
41+
6042
# Import based on subclass implementation
6143
try:
6244
collection = self.import_typst(temp_file, origin_to_char)
6345
elapsed_time_ms = (time.perf_counter() - start_time) * 1000
6446
self.report(
6547
{"INFO"},
66-
f"🦢 Typst Importer: {self.text_name} rendered in {elapsed_time_ms:.2f} ms as {collection.name}",
48+
f"🦢 Typst Importer: textbox content rendered in {elapsed_time_ms:.2f} ms as {collection.name}",
6749
)
6850
return {"FINISHED"}
6951
except Exception as e:
@@ -73,17 +55,17 @@ def execute(self, context):
7355
# Clean up temporary file
7456
if temp_file.exists():
7557
temp_file.unlink()
76-
58+
7759
def import_typst(self, typst_file: Path, origin_to_char: bool = False):
7860
"""Override in subclasses to specify import type"""
7961
raise NotImplementedError
8062

8163

82-
class ImportFromTextEditorAsCurveOperator(ImportFromTextEditorOperator):
83-
"""Import text editor document as curves"""
84-
bl_idname = "import_scene.import_text_editor_curve"
85-
bl_label = "Import from Text Editor as Curve"
86-
64+
class ImportFromTextboxAsCurveOperator(ImportFromTextboxOperator):
65+
"""Import textbox content as curves"""
66+
bl_idname = "import_scene.import_textbox_curve"
67+
bl_label = "Import from Textbox as Curve"
68+
8769
def import_typst(self, typst_file: Path, origin_to_char: bool = False):
8870
return typst_to_blender_curves(
8971
typst_file,
@@ -92,11 +74,11 @@ def import_typst(self, typst_file: Path, origin_to_char: bool = False):
9274
)
9375

9476

95-
class ImportFromTextEditorAsMeshOperator(ImportFromTextEditorOperator):
96-
"""Import text editor document as mesh"""
97-
bl_idname = "import_scene.import_text_editor_mesh"
98-
bl_label = "Import from Text Editor as Mesh"
99-
77+
class ImportFromTextboxAsMeshOperator(ImportFromTextboxOperator):
78+
"""Import textbox content as mesh"""
79+
bl_idname = "import_scene.import_textbox_mesh"
80+
bl_label = "Import from Textbox as Mesh"
81+
10082
def import_typst(self, typst_file: Path, origin_to_char: bool = False):
10183
return typst_to_blender_curves(
10284
typst_file,
@@ -105,16 +87,15 @@ def import_typst(self, typst_file: Path, origin_to_char: bool = False):
10587
)
10688

10789

108-
class ImportFromTextEditorAsUnfilledCurveOperator(ImportFromTextEditorOperator):
109-
"""Import text editor document as unfilled curves"""
110-
bl_idname = "import_scene.import_text_editor_unfilled_curve"
111-
bl_label = "Import from Text Editor as Unfilled Curve"
112-
90+
class ImportFromTextboxAsUnfilledCurveOperator(ImportFromTextboxOperator):
91+
"""Import textbox content as unfilled curves"""
92+
bl_idname = "import_scene.import_textbox_unfilled_curve"
93+
bl_label = "Import from Textbox as Unfilled Curve"
94+
11395
def import_typst(self, typst_file: Path, origin_to_char: bool = False):
11496
return typst_to_blender_curves(
11597
typst_file,
11698
convert_to_mesh=False,
11799
convert_to_unfilled_path=True,
118100
origin_to_char=origin_to_char,
119101
)
120-

0 commit comments

Comments
 (0)