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