Skip to content

basic examples app #795

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
140 changes: 140 additions & 0 deletions examples/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,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()
Loading