jdegenstein commited on
Commit
ede9cb3
·
unverified ·
1 Parent(s): 1b64cf9

Create cadviewer.py

Browse files
Files changed (1) hide show
  1. cadviewer.py +121 -0
cadviewer.py ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ """
2
+ nicegui cadviewer
3
+
4
+ name: cadviewer.py
5
+ by: jdegenstein
6
+ date: January 24, 2025
7
+
8
+ desc:
9
+
10
+ This module creates a graphical window with a text editor and CAD viewer (based on ocp_vscode).
11
+ The graphical user interface is based on nicegui and spawns the necessary subprocess and allows
12
+ for re-running the user-supplied script and displaying the results.
13
+
14
+ Key Features:
15
+ - Has a run button for executing user code
16
+ - Has a keyboard shortcut of CTRL-Enter to run the user code
17
+
18
+ license:
19
+
20
+ Copyright 2025 jdegenstein
21
+
22
+ Licensed under the Apache License, Version 2.0 (the "License");
23
+ you may not use this file except in compliance with the License.
24
+ You may obtain a copy of the License at
25
+
26
+ http://www.apache.org/licenses/LICENSE-2.0
27
+
28
+ Unless required by applicable law or agreed to in writing, software
29
+ distributed under the License is distributed on an "AS IS" BASIS,
30
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31
+ See the License for the specific language governing permissions and
32
+ limitations under the License.
33
+
34
+ """
35
+
36
+ from nicegui import app, ui
37
+ from nicegui.events import KeyEventArguments
38
+ import subprocess
39
+
40
+ app.native.window_args["resizable"] = True
41
+ app.native.start_args["debug"] = True
42
+ # app.native.settings['ALLOW_DOWNLOADS'] = True # export "downloads" ?
43
+ app.native.settings["MATPLOTLIB"] = False
44
+
45
+ editor_fontsize = 18
46
+ # TODO: consider separate editor execution thread from nicegui thread
47
+
48
+
49
+ # run ocp_vscode in a subprocess
50
+ def startup_all():
51
+ global ocpcv_proc
52
+ # spawn separate viewer process
53
+ ocpcv_proc = subprocess.Popen(["python", "-m", "ocp_vscode"])
54
+ # pre-import build123d and ocp_vscode in main thread
55
+ exec("from build123d import *\nfrom ocp_vscode import *")
56
+
57
+
58
+ def button_run_callback():
59
+ exec(code.value)
60
+
61
+
62
+ def shutdown_all():
63
+ ocpcv_proc.kill()
64
+ # ocpcv_proc.terminate() # TODO: investigate best cross-platform solution
65
+ app.shutdown()
66
+
67
+
68
+ app.on_startup(startup_all)
69
+
70
+ button_frac = 0.05
71
+
72
+
73
+ with ui.splitter().classes(
74
+ "w-full h-[calc(100vh-2rem)] no-wrap items-stretch border"
75
+ ) as splitter:
76
+ with splitter.before:
77
+ with ui.column().classes("w-full items-stretch border"):
78
+ with ui.row():
79
+ with ui.column().classes("w-1/3"):
80
+ ui.button(
81
+ "Run Code", icon="send", on_click=lambda: button_run_callback()
82
+ ).classes(f"h-[calc(100vh*{button_frac}-3rem)]")
83
+ # ui.button('shutdown', on_click=lambda: shutdown_all()) # just close the window
84
+ code = (
85
+ ui.codemirror(
86
+ 'print("Edit me!")\nprint("hello world")',
87
+ language="Python",
88
+ theme="vscodeLight",
89
+ )
90
+ .classes(f"h-[calc(100vh*{1-button_frac}-3rem)]")
91
+ .style(f"font-size: {editor_fontsize}px")
92
+ )
93
+ with splitter.after:
94
+ with ui.column().classes("w-full items-stretch border"):
95
+ ocpcv = (
96
+ ui.element("iframe")
97
+ .props('src="http://127.0.0.1:3939/viewer"')
98
+ .classes("h-[calc(100vh-3rem)]")
99
+ )
100
+
101
+
102
+ # handle the CTRL + Enter run shortcut:
103
+ def handle_key(e: KeyEventArguments):
104
+ if e.modifiers.ctrl and e.action.keydown:
105
+ if e.key.enter:
106
+ button_run_callback()
107
+
108
+
109
+ keyboard = ui.keyboard(on_key=handle_key)
110
+ # TODO: consider separating this module and how best to organize it (if name == main, etc.)
111
+ app.on_shutdown(shutdown_all) # register shutdown handler
112
+ ui.run(
113
+ native=True,
114
+ window_size=(1800, 900),
115
+ title="nicegui-cadviewer",
116
+ fullscreen=False,
117
+ reload=False,
118
+ )
119
+ # ui.run(native=True, window_size=(1800, 900), fullscreen=False, reload=True) #use reload=True when developing rapidly, False helps exit behavior
120
+
121
+ # layout info https://github.com/zauberzeug/nicegui/discussions/1937