# `imgui_bundle.immapp` ImmApp: runs an app in one call, with the bundle's add-ons set up: ImPlot, ImPlot3D, markdown, LaTeX, the node editor, ImAnim. `immapp.run(gui_function, window_title="My app", with_implot=True)` is the usual way to start an app of the bundle; `AddOnsParams` lists the add-ons. It relies on Hello ImGui: a `hello_imgui.RunnerParams` gives full control over the window, the docking and the callbacks. It also holds helpers: sizes in em units (`em_size`, `em_to_vec2`), a render loop driven by the app (`manual_render`), plots and widgets inside the node editor, and the code utilities of the demos. Generated from the Python stubs of Dear ImGui Bundle. Each entry gives its Python signature, its C++ declaration ("C++:"), and the first paragraph of its doc. The Python names follow the C++ ones (`ImGui::Button` is `imgui.button`, `ImPlotFlags_` is `implot.Flags_`). The full docs: https://imgui-bundle.pages.dev/doc/api/immapp/ Demos using it (all the demos: https://imgui-bundle.pages.dev/llms/demos.txt): - What is an Immediate GUI: With Dear ImGui, your GUI code is simple and direct: no widget trees, no callbacks, no state synchronization. Python: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_python/demos_immapp/welcome_imm_mode.py, C++: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_cpp/demos_immapp/welcome_imm_mode.cpp - Hello world, in two lines: ImmApp opens the window, runs the loop, and calls your GUI function at every frame: immapp.run(gui) is all it takes. Python: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_python/demos_immapp/demo_hello_world.py, C++: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_cpp/demos_immapp/demo_hello_world.cpp - A parametric curve: Turn the knobs, or click Random: the curve follows at once. Python: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_python/demos_immapp/demo_parametric_curve.py, C++: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_cpp/demos_immapp/demo_parametric_curve.cpp - Assets and add-ons: Load images and icons from your assets folder, and use two add-ons: markdown and ImPlot. Python: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_python/demos_immapp/demo_assets_addons.py, C++: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_cpp/demos_immapp/demo_assets_addons.cpp - immapp.testing: scripted runs: Easy automated tests with immapp.testing, a thin layer on the test engine: a script drives the app, then exits. Python: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_python/demos_immapp/demo_immapp_testing.py, C++: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_cpp/demos_immapp/demo_immapp_testing.cpp - Knobs, toggles, spinners and more: Knobs, toggle switches, spinners, a command palette, a dock-like cool bar: widgets beyond Dear ImGui's own. Python: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_python/demo_widgets.py, C++: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_cpp/demo_widgets.cpp - Context managers (imgui_ctx): In Python, with imgui_ctx.begin("Window"): replaces a begin() / end() pair, and the end() can no longer be forgotten. Python: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_python/demos_python_specifics/demo_python_context_manager.py - Async: compute beside the GUI: The GUI runs as an asyncio task, while a Python loop keeps computing. Python: https://github.com/pthom/imgui_bundle/blob/main/bindings/imgui_bundle/demos_python/demos_python_specifics/demo_run_async.py ### runner.h class AddOnsParams C++: struct AddOnsParams /////////////////////////////////////////////////////////////////////////////////////// with_implot: bool with_implot3d: bool with_markdown: bool with_node_editor: bool with_tex_inspect: bool with_im_anim: bool with_latex: bool with_node_editor_config: Optional[NodeEditorConfig] update_node_editor_colors_from_imgui_colors: bool with_markdown_options: Optional[RichMd.MarkdownOptions] def __init__(self, with_implot: bool = False, with_implot3d: bool = False, with_markdown: bool = False, with_node_editor: bool = False, with_tex_inspect: bool = False, with_im_anim: bool = False, with_latex: bool = False, with_node_editor_config: Optional[NodeEditorConfig] = None, update_node_editor_colors_from_imgui_colors: bool = True, with_markdown_options: Optional[RichMd.MarkdownOptions] = None) -> None ### Helpers to run an app from C++ #### Run an application using HelloImGui params + some addons def run(runner_params: HelloImGui.RunnerParams, add_ons_params: Optional[AddOnsParams] = None) -> None C++: void Run(HelloImGui::RunnerParams& runnerParams, const AddOnsParams& addOnsParams = AddOnsParams()); def run(simple_params: HelloImGui.SimpleRunnerParams, add_ons_params: Optional[AddOnsParams] = None) -> None C++: void Run(const HelloImGui::SimpleRunnerParams& simpleParams, const AddOnsParams& addOnsParams = AddOnsParams()); def run(gui_function: VoidFunction, window_title: str = '', window_size_auto: bool = False, window_restore_previous_geometry: bool = False, window_size: Optional[ScreenSize] = None, fps_idle: float = 10.0, top_most: bool = False, ini_disable: bool = False, with_implot: bool = False, with_implot3d: bool = False, with_markdown: bool = False, with_node_editor: bool = False, with_tex_inspect: bool = False, with_im_anim: bool = False, with_latex: bool = False, with_node_editor_config: Optional[NodeEditorConfig] = None, with_markdown_options: Optional[RichMd.MarkdownOptions] = None) -> None C++: void Run( // HelloImGui::SimpleRunnerParams below: const VoidFunction& guiFunction, const std::string& windowTitle = "", bool windowSizeAuto = false, bool windowRestorePreviousGeometry = false, const ScreenSize& windowSize = DefaultWindowSize, float fpsIdle = 10.f, bool topMost = false, bool iniDisable = false, // AddOnsParams below: bool withImplot = false, bool withImplot3d = false, bool withMarkdown = false, bool withNodeEditor = false, bool withTexInspect = false, bool withImAnim = false, bool withLatex = false, #ifdef IMGUI_BUNDLE_WITH_IMGUI_NODE_EDITOR const std::optional& withNodeEditorConfig = std::nullopt, #endif const std::optional & withMarkdownOptions = std::nullopt ); def run_with_markdown(gui_function: VoidFunction, window_title: str = '', window_size_auto: bool = False, window_restore_previous_geometry: bool = False, window_size: Optional[ScreenSize] = None, fps_idle: float = 10.0, top_most: bool = False, ini_disable: bool = False, with_implot: bool = False, with_implot3d: bool = False, with_node_editor: bool = False, with_tex_inspect: bool = False, with_im_anim: bool = False, with_latex: bool = False, with_node_editor_config: Optional[NodeEditorConfig] = None, with_markdown_options: Optional[RichMd.MarkdownOptions] = None) -> None C++: void RunWithMarkdown( // HelloImGui::SimpleRunnerParams below: const VoidFunction& guiFunction, const std::string& windowTitle = "", bool windowSizeAuto = false, bool windowRestorePreviousGeometry = false, const ScreenSize& windowSize = DefaultWindowSize, float fpsIdle = 10.f, bool topMost = false, bool iniDisable = false, // AddOnsParams below: bool withImplot = false, bool withImplot3d = false, bool withNodeEditor = false, bool withTexInspect = false, bool withImAnim = false, bool withLatex = false, #ifdef IMGUI_BUNDLE_WITH_IMGUI_NODE_EDITOR const std::optional& withNodeEditorConfig = std::nullopt, #endif const std::optional & withMarkdownOptions = std::nullopt ); Run an application with markdown def em_size() -> float C++: float EmSize(); def em_size(nb_lines: float) -> float C++: float EmSize(float nbLines); EmSize() returns the visible font size on the screen. For good results on HighDPI screens, always scale your widgets and windows relatively to this size. It is somewhat comparable to the [em CSS Unit](https://lyty.dev/css/css-unit.html). EmSize() = ImGui::GetFontSize() def em_to_vec2(x: float, y: float) -> ImVec2 C++: ImVec2 EmToVec2(float x, float y); def em_to_vec2(v: ImVec2Like) -> ImVec2 C++: ImVec2 EmToVec2(ImVec2 v); def pixels_to_em(pixels: ImVec2Like) -> ImVec2 C++: ImVec2 PixelsToEm(ImVec2 pixels); PixelsToEm() converts a Vec2 in pixels to a Vec2 in em def pixel_size_to_em(pixel_size: float) -> float C++: float PixelSizeToEm(float pixelSize); PixelSizeToEm() converts a size in pixels to a size in em ### Utility for ImGui node editor & NanoVG def default_node_editor_context() -> NodeEditorContext C++: NodeEditorContext* DefaultNodeEditorContext(); def default_node_editor_config() -> NodeEditorConfig C++: NodeEditorConfig* DefaultNodeEditorConfig(); def node_editor_settings_location(runner_params: HelloImGui.RunnerParams) -> str C++: std::string NodeEditorSettingsLocation(const HelloImGui::RunnerParams& runnerParams); NodeEditorSettingsLocation returns the path to the json file for the node editor settings. def has_node_editor_settings(runner_params: HelloImGui.RunnerParams) -> bool C++: bool HasNodeEditorSettings(const HelloImGui::RunnerParams& runnerParams); HasNodeEditorSettings returns True if the json file for the node editor settings exists. def delete_node_editor_settings(runner_params: HelloImGui.RunnerParams) -> None C++: void DeleteNodeEditorSettings(const HelloImGui::RunnerParams& runnerParams); DeleteNodeEditorSettings deletes the json file for the node editor settings. class manual_render @staticmethod def setup_from_runner_params(runner_params: HelloImGui.RunnerParams, add_ons_params: Optional[AddOnsParams] = None) -> None C++: void SetupFromRunnerParams(HelloImGui::RunnerParams& runnerParams, const AddOnsParams& addOnsParams = AddOnsParams()); Initializes the rendering with the full customizable `RunnerParams`. This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.). A reference to the user's `RunnerParams` is kept internally (similar to ImmApp::Run). @staticmethod def setup_from_simple_runner_params(simple_params: HelloImGui.SimpleRunnerParams, add_ons_params: Optional[AddOnsParams] = None) -> None C++: void SetupFromSimpleRunnerParams(const HelloImGui::SimpleRunnerParams& simpleParams, const AddOnsParams& addOnsParams = AddOnsParams()); Initializes the rendering with `SimpleRunnerParams`. This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.). @staticmethod def setup_from_gui_function(gui_function: VoidFunction, window_title: str = '', window_size_auto: bool = False, window_restore_previous_geometry: bool = False, window_size: Optional[ScreenSize] = None, fps_idle: float = 10.0, top_most: bool = False, ini_disable: bool = False, with_implot: bool = False, with_implot3d: bool = False, with_markdown: bool = False, with_node_editor: bool = False, with_tex_inspect: bool = False, with_im_anim: bool = False, with_latex: bool = False, with_node_editor_config: Optional[NodeEditorConfig] = None, with_markdown_options: Optional[RichMd.MarkdownOptions] = None) -> None C++: void SetupFromGuiFunction( const VoidFunction& guiFunction, const std::string& windowTitle = "", bool windowSizeAuto = false, bool windowRestorePreviousGeometry = false, const ScreenSize& windowSize = DefaultWindowSize, float fpsIdle = 10.f, bool topMost = false, bool iniDisable = false, // AddOnsParams below: bool withImplot = false, bool withImplot3d = false, bool withMarkdown = false, bool withNodeEditor = false, bool withTexInspect = false, bool withImAnim = false, bool withLatex = false, #ifdef IMGUI_BUNDLE_WITH_IMGUI_NODE_EDITOR const std::optional& withNodeEditorConfig = std::nullopt, #endif const std::optional & withMarkdownOptions = std::nullopt ); Initializes the renderer with a simple GUI function and additional parameters. This will initialize the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.). @staticmethod def render() -> None C++: void Render(); Renders the current frame. Should be called regularly to maintain the application's responsiveness. @staticmethod def tear_down() -> None C++: void TearDown(); Tears down the renderer and releases all associated resources. This will release the platform backend (SDL, Glfw, etc.) and the rendering backend (OpenGL, Vulkan, etc.). After calling `tear_down()`, the InitFromXXX can be called with new parameters. ### immapp_widgets.h def begin_plot_in_node_editor(title_id: str, size: Optional[ImVec2Like] = None, flags: ImPlotFlags = 0) -> bool C++: bool BeginPlotInNodeEditor(const char* title_id, const ImVec2& size=ImVec2(-1,0), ImPlotFlags flags=0); def end_plot_in_node_editor() -> None C++: void EndPlotInNodeEditor(); def show_resizable_plot_in_node_editor(title_id: str, size_pixels: ImVec2Like, plot_function: VoidFunction, flags: ImPlotFlags = 0, resize_handle_size_em: float = 1.0) -> ImVec2 C++: ImVec2 ShowResizablePlotInNodeEditor( const char* title_id, // plot title const ImVec2& size_pixels, // plot size (will be updated if resized by the user) VoidFunction plotFunction, // your function to draw the plot ImPlotFlags flags=0, float resizeHandleSizeEm=1.0f ); ShowResizablePlotInNodeEditor: shows a resizable plot inside a node Returns the new size of the plot def show_resizable_plot_in_node_editor_em(title_id: str, size_em: ImVec2Like, plot_function: VoidFunction, flags: ImPlotFlags = 0, resize_handle_size_em: float = 1.0) -> ImVec2 C++: ImVec2 ShowResizablePlotInNodeEditor_Em( const char* title_id, // plot title const ImVec2& size_em, // plot size (will be updated if resized by the user) VoidFunction plotFunction, // your function to draw the plot ImPlotFlags flags=0, float resizeHandleSizeEm=1.0f ); ShowResizablePlotInNodeEditor_Em: shows a resizable plot inside a node Returns the new size of the plot. Units are in em. def widget_with_resize_handle_in_node_editor(id: str, gui_function: VoidFunction, resize_handle_size_em: float = 1.0) -> ImVec2 C++: ImVec2 WidgetWithResizeHandle_InNodeEditor( const char* id, VoidFunction guiFunction, // your function to draw the widget float resizeHandleSizeEm=1.0f ); WidgetWithResizeHandle_InNodeEditor: shows a resizable widget inside a node Returns the new size of the widget. def widget_with_resize_handle_in_node_editor_em(id: str, gui_function: VoidFunction, resize_handle_size_em: float = 1.0) -> ImVec2 C++: ImVec2 WidgetWithResizeHandle_InNodeEditor_Em( const char* id, VoidFunction guiFunction, // your function to draw the widget float resizeHandleSizeEm=1.0f ); WidgetWithResizeHandle_InNodeEditor_Em: shows a resizable widget inside a node Returns the new size of the widget. Size is in em. ### clock.h def clock_seconds() -> float C++: double ClockSeconds(); Chronometer in seconds ### code_utils.h #### Submodule code_utils class code_utils @staticmethod def unindent(code: str, is_markdown: bool) -> str C++: std::string Unindent(const std::string& code, bool is_markdown); @staticmethod def unindent_code(code: str) -> str C++: std::string UnindentCode(const std::string& code); @staticmethod def unindent_markdown(code: str) -> str C++: std::string UnindentMarkdown(const std::string& code); ### snippets.h #### Submodule snippets class snippets enum SnippetLanguage C++: enum class SnippetLanguage cpp = 0 hlsl = 1 glsl = 2 c = 3 sql = 4 angel_script = 5 lua = 6 python = 7 markdown = 8 plain_text = 9 # no highlighting enum SnippetTheme C++: enum class SnippetTheme auto = 0 # Automatic based on bg color dark = 1 light = 2 @staticmethod def default_snippet_language() -> SnippetLanguage C++: inline SnippetLanguage DefaultSnippetLanguage(); DefaultSnippetLanguage: Cpp, or Python when the host defines IMGUI_RICHMD_DEFAULT_SNIPPET_LANGUAGE_PYTHON (Python bindings) class SnippetData C++: struct SnippetData code: str language: snippets.SnippetLanguage palette: snippets.SnippetTheme show_copy_button: bool # Displayed on top of the editor (Top Right corner) show_cursor_position: bool # Show line and column number displayed_filename: str # Displayed on top of the editor height_in_lines: int # Number of visible lines in the editor max_height_in_lines: int read_only: bool # Snippets are read-only by default border: bool # Draw a border around the editor de_indent_code: bool # Keep the code indentation, but remove main indentation, add_final_empty_line: bool # Add an empty line at the end of the code if missing on_hover: Callable[[str, int], bool] on_context_menu: Callable[[str, int], bool] def __init__(self, code: str = '', language: snippets.SnippetLanguage = snippets.default_snippet_language(), palette: snippets.SnippetTheme = snippets.SnippetTheme.auto, show_copy_button: bool = True, show_cursor_position: bool = True, displayed_filename: str = '', height_in_lines: int = 0, max_height_in_lines: int = 40, read_only: bool = True, border: bool = False, de_indent_code: bool = True, add_final_empty_line: bool = False) -> None @staticmethod def show_editable_code_snippet(label_id: str, snippet_data: SnippetData, width: float = 0.0, override_height_in_lines: int = 0) -> bool C++: bool ShowEditableCodeSnippet(const std::string& label_id, SnippetData* snippetData, float width = 0.f, int overrideHeightInLines = 0); @staticmethod def show_code_snippet(snippet_data: SnippetData, width: float = 0.0, override_height_in_lines: int = 0) -> None C++: void ShowCodeSnippet(const SnippetData& snippetData, float width = 0.f, int overrideHeightInLines = 0); @staticmethod def show_side_by_side_snippets(snippet1: SnippetData, snippet2: SnippetData, hide_if_empty: bool = True, equal_visible_lines: bool = True) -> None C++: void ShowSideBySideSnippets(const SnippetData& snippet1, const SnippetData& snippet2, bool hideIfEmpty = true, bool equalVisibleLines = true); @staticmethod def show_side_by_side_snippets(snippets: List[SnippetData], hide_if_empty: bool = True, equal_visible_lines: bool = True) -> None C++: void ShowSideBySideSnippets(const std::vector& snippets , bool hideIfEmpty = true, bool equalVisibleLines = true); def render_markdown_doc_panel(doc: str, height_em: float = 20.0) -> None Render a markdown documentation panel with a light theme, inside a resizable child window. Useful for showing docstrings or documentation at the top of a demo. def download_url_bytes(url: str, timeout_s: float = 10.0) -> bytes Download data from a URL synchronously. Works on both desktop (urllib) and Pyodide (sync XMLHttpRequest). Returns the downloaded bytes, or empty bytes on failure (an error status included). This blocks the GUI: from a GUI function, prefer start_download(). def decode_image(file_bytes: bytes, channels: int = 3) -> np.ndarray Decodes an image file's bytes (PNG, JPEG, BMP, GIF, TGA...; the format is detected), e.g. downloaded with start_download(): a numpy array of uint8, (height, width, channels). channels: 3 = RGB, 4 = RGBA, 1 = gray (then (height, width)). Raises ValueError when the bytes are not an image. No OpenCV ... class Download A request running in the background, started by start_download(). Look at `done` at each frame, then at `error` and `data`. url: str @property def done(self) -> bool True once the request ended, with a success or a failure @property def status(self) -> int The HTTP status, once done; 0 for a network failure or a timeout @property def data(self) -> bytes The body of the response, once done (also with an error status) @property def error(self) -> str Empty on success (a 2xx status). Else the error status with the start of the body, or the network failure def start_download(url: str, method: str = 'GET', json_body: object = None, timeout_s: float = 30.0, headers: dict[str, str] | None = None) -> Download Starts a request that does not block the GUI: a thread on the desktop, a fetch in Pyodide. Call it from a GUI function, and look at the result's `done` at each frame: