-
Notifications
You must be signed in to change notification settings - Fork 64
Expand file tree
/
Copy pathapp.py
More file actions
140 lines (99 loc) · 4.18 KB
/
app.py
File metadata and controls
140 lines (99 loc) · 4.18 KB
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
from pathlib import Path
from collections import OrderedDict
import wgpu
from imgui_bundle import imgui
from wgpu.gui.auto import WgpuCanvas, run
from wgpu.utils.imgui import ImguiRenderer
import subprocess
canvas = WgpuCanvas(title="imgui", size=(1200, 900))
adapter = wgpu.gpu.request_adapter_sync(power_preference="high-performance")
device = adapter.request_device_sync()
imgui_renderer = ImguiRenderer(device, canvas)
example_paths: OrderedDict[Path, list[Path]] = OrderedDict()
# grab all examples as a dict of lists, {example_dir: [e1.py, e2.py, ...]}
for d in sorted(Path(__file__).parent.glob("*")):
if d.is_dir():
if d.name.startswith("."):
continue
if d.name in ["tests", "screenshots"]:
continue
example_paths[d] = sorted(d.glob("*.py"))
# the first example
example_dir0 = list(example_paths.keys())[0]
example0 = example_paths[example_dir0][0]
# set the first example to be selected
selection = (example_dir0, example0)
# read the first example
with open(selection[1], "r") as f:
example_src = f.read()
# used to determine if a different example has been selected between frame draws
new_selection: bool = False
def update_gui():
global selection
global new_selection
global example_src
example_double_clicked = False
w, h = canvas.get_physical_size()
imgui.new_frame()
menu_size = (340, h)
menu_pos = (0, 0)
imgui.set_next_window_size(menu_size)
imgui.set_next_window_pos(menu_pos)
flags = imgui.WindowFlags_.no_collapse | imgui.WindowFlags_.no_resize
# window with the list of all examples
imgui.begin("Examples", None, flags=flags)
# add menu item for each example
for example_dir in example_paths.keys():
# each example dir
imgui.text(example_dir.name)
imgui.indent(10)
# each individual example
for example in example_paths[example_dir]:
is_selected = selection[0] == example_dir and selection[1] == example
selection_changed, selected = imgui.selectable(example.name, p_selected=is_selected)
# update selection dir and path if this example file is selected
if selected:
selection = (example_dir, example)
# if double-clicked, used to flag running the example
if imgui.is_mouse_double_clicked(0):
example_double_clicked = True
if selection_changed:
# new example file is selected on this frame update
new_selection = True
imgui.unindent(10)
imgui.separator()
imgui.end()
# window that displays text of example
source_window_size = (w - menu_size[0], h)
imgui.set_next_window_size(source_window_size)
imgui.set_next_window_pos((menu_size[0], 0))
imgui.begin(f"{selection[0].name}/{selection[1].name}", None, flags)
# path to the selected example file
selected_example = selection[1]
# if this example file has just been selected in this render frame update
# then update the example_src by reading the file from disk
if new_selection:
with open(selected_example, "r") as f:
example_src = f.read()
# new_selection = False prevents it from reading from disk every time the frame is rendered
# this allows any changes from the user to be kept, while the file on disk remains unchanged
# so the user can make a small change to the file in the text editor and run it with the changes!
new_selection = False
# basic text editor
src_changed, example_src = imgui.input_text_multiline(".", example_src, (source_window_size[0], h - 60))
clicked = imgui.button("Run example")
# run the example if the button is clicked or if the item is double-clicked
if clicked or example_double_clicked:
subprocess.Popen(["python", "-c", example_src])
imgui.end()
imgui.end_frame()
imgui.render()
return imgui.get_draw_data()
# set the GUI update function that gets called to return the draw data
imgui_renderer.set_gui(update_gui)
def draw_frame():
imgui_renderer.render()
canvas.request_draw()
if __name__ == "__main__":
canvas.request_draw(draw_frame)
run()