# Part of ImGui Bundle - MIT License - Copyright (c) 2022-2026 Pascal Thomet - https://github.com/pthom/imgui_bundle import importlib.util import sys if importlib.util.find_spec("numpy") is None: print( "Dear ImGui Bundle Explorer requires numpy!\n" "Please install it with:\n" " pip install numpy\n" "or\n" " uv pip install numpy", file=sys.stderr, ) sys.exit(1) from typing import List, Callable from types import ModuleType from dataclasses import dataclass, field from imgui_bundle import imgui, hello_imgui, immapp from imgui_bundle.immapp import static from imgui_bundle.demos_python import demo_text_edit from imgui_bundle.demos_python import demo_imgui_bundle_intro from imgui_bundle.demos_python import demo_imgui_show_demo_window from imgui_bundle.demos_python import demo_widgets from imgui_bundle.demos_python import demo_implot from imgui_bundle.demos_python import demo_imgui_md from imgui_bundle.demos_python import demo_immvision_launcher from imgui_bundle.demos_python import demo_imguizmo_launcher from imgui_bundle.demos_python import demo_tex_inspect_launcher from imgui_bundle.demos_python import demo_node_editor_launcher from imgui_bundle.demos_python import demo_immapp_launcher from imgui_bundle.demos_python import demo_nanovg_launcher from imgui_bundle.demos_python import demo_themes from imgui_bundle.demos_python import demo_logger from imgui_bundle.demos_python import demo_im_anim from imgui_bundle.demos_python import demo_utils _show_code_states: dict[str, bool] = {} def show_module_demo(demo_filename: str, demo_function: Callable[[], None], show_code: bool = False) -> None: if imgui.get_frame_count() < 2: # cf https://github.com/pthom/imgui_bundle/issues/293 return if show_code: current = _show_code_states.get(demo_filename, False) _, current = imgui.checkbox("Show code##" + demo_filename, current) _show_code_states[demo_filename] = current if current: demo_utils.show_python_vs_cpp_file(demo_filename, 40) demo_function() @dataclass class DemoDetails: label: str demo_module: ModuleType show_code: bool = False @dataclass class DemoGroup: """A group of demos shown as collapsing headers inside a single tab.""" label: str demos: List[DemoDetails] = field(default_factory=list) def _show_group_gui(group: DemoGroup) -> None: """Gui function for a grouped tab: each sub-demo is a collapsing header.""" if imgui.get_frame_count() < 2: return for demo in group.demos: demo_module_name = demo.demo_module.__name__.split(".")[-1] if imgui.collapsing_header(demo.label): imgui.indent() show_module_demo(demo_module_name, demo.demo_module.demo_gui, demo.show_code) imgui.unindent() def make_params() -> tuple[hello_imgui.RunnerParams, immapp.AddOnsParams]: print( f"For information, demos sources are available in {demo_utils.api_demos.demos_python_folder()}" ) ################################################################################################ # Part 1: Define the runner params ################################################################################################ # Hello ImGui params (they hold the settings as well as the Gui callbacks) runner_params = hello_imgui.RunnerParams() # Window size and title runner_params.app_window_params.window_title = ( "Dear ImGui Bundle Explorer" ) runner_params.app_window_params.window_geometry.size = (1400, 950) # Menu bar runner_params.imgui_window_params.show_menu_bar = True runner_params.imgui_window_params.show_status_bar = True runner_params.ini_clear_previous_settings = True ################################################################################################ # Part 2: Define the application layout and windows ################################################################################################ # First, tell HelloImGui that we want full screen dock space (this will create "MainDockSpace") runner_params.imgui_window_params.default_imgui_window_type = ( hello_imgui.DefaultImGuiWindowType.provide_full_screen_dock_space ) # In this demo, we also demonstrate multiple viewports. # you can drag windows outside out the main window in order to put their content into new native windows runner_params.imgui_window_params.enable_viewports = True # # Define our dockable windows : each window provide a Gui callback, and will be displayed # in a docking split. # dockable_windows: List[hello_imgui.DockableWindow] = [] # --- Standalone tabs (no grouping) --- standalone_demos = [ DemoDetails("Intro", demo_imgui_bundle_intro), DemoDetails("Dear ImGui", demo_imgui_show_demo_window), DemoDetails("Demo Apps", demo_immapp_launcher), ] for demo in standalone_demos: window = hello_imgui.DockableWindow() window.label = demo.label window.dock_space_name = "MainDockSpace" demo_module_name = demo.demo_module.__name__.split(".")[-1] def make_win_fn(mod_name: str, mod: ModuleType, sc: bool) -> Callable[[], None]: def win_fn() -> None: show_module_demo(mod_name, mod.demo_gui, sc) return win_fn window.gui_function = make_win_fn(demo_module_name, demo.demo_module, demo.show_code) dockable_windows.append(window) # --- Grouped tabs (sub-demos shown as collapsing headers) --- groups = [ DemoGroup("Visualization", [ DemoDetails("Plots with ImPlot and ImPlot3D", demo_implot), DemoDetails("ImmVision - Image analyzer", demo_immvision_launcher), DemoDetails("Tex Inspect - Texture Inspector", demo_tex_inspect_launcher), ]), DemoGroup("Widgets", [ DemoDetails("Misc Widgets - Knobs, Toggles, ...", demo_widgets, show_code=True), DemoDetails("Logger - Log Window Widget", demo_logger, show_code=True), DemoDetails("ImGuizmo - Immediate Mode 3D Gizmo", demo_imguizmo_launcher), DemoDetails("Markdown - Rich Text Rendering", demo_imgui_md, show_code=True), DemoDetails("Text Editor - Code Editing Widget", demo_text_edit), ]), DemoGroup("Tools", [ DemoDetails("Node Editor - Visual Node Graphs", demo_node_editor_launcher), DemoDetails("Themes - Style & Color Customization", demo_themes, show_code=True), DemoDetails("ImAnim - Animation Library", demo_im_anim), DemoDetails("NanoVG - 2D Vector Drawing", demo_nanovg_launcher), ]), ] for group in groups: window = hello_imgui.DockableWindow() window.label = group.label window.dock_space_name = "MainDockSpace" def make_group_fn(g: DemoGroup) -> Callable[[], None]: def win_fn() -> None: _show_group_gui(g) return win_fn window.gui_function = make_group_fn(group) dockable_windows.append(window) runner_params.docking_params.dockable_windows = dockable_windows # the main gui is only responsible to give focus to ImGui Bundle dockable window @static(nb_frames=0) def show_gui(): if show_gui.nb_frames == 1: # Focus cannot be given at frame 0, since some additional windows will # be created after (and will steal the focus) runner_params.docking_params.focus_dockable_window("Dear ImGui Bundle") show_gui.nb_frames += 1 def show_status_bar(): from imgui_bundle import __version__, __build_number__ imgui.set_next_item_width(imgui.get_content_region_avail().x / 10) _, imgui.get_style().font_scale_main = imgui.slider_float("Font scale", imgui.get_style().font_scale_main, 0.5, 5) imgui.same_line(spacing=hello_imgui.em_size(4)) imgui.text_disabled(f"Dear ImGui Bundle Explorer - v{__version__} build {__build_number__}") runner_params.callbacks.show_status = show_status_bar runner_params.callbacks.show_gui = show_gui if "test_engine" in dir(imgui): # only enable test engine if available (i.e. if imgui bundle was compiled with it) runner_params.use_imgui_test_engine = True def setup_imgui_config() -> None: imgui.get_io().config_flags |= imgui.ConfigFlags_.nav_enable_keyboard.value runner_params.callbacks.setup_imgui_config = setup_imgui_config ################################################################################################ # Part 3: Run the app ################################################################################################ addons = immapp.AddOnsParams() addons.with_markdown = True addons.with_latex = True addons.with_node_editor = True addons.with_implot = True addons.with_implot3d = True addons.with_im_anim = True return runner_params, addons def main(): from imgui_bundle import __version__, __build_number__, compilation_time print(f"Dear ImGui Bundle Explorer - v{__version__} build {__build_number__}, {compilation_time()}") runner_params, addons = make_params() immapp.run(runner_params=runner_params, add_ons_params=addons) if __name__ == "__main__": main()