# ImGui Context Manager Suite Design ## Status Proposed — 2026-05-11 ## Context The `src/gui_2.py` file contains ~50 `imgui.begin()` / `imgui.end()` pairs scattered across 5900+ lines. Dear PyGui (and ImGui) uses a procedural API where every `begin_X()` requires a matching `end_X()`. This creates two problems: 1. **Error-prone for AI agents** — forgetting an `end()` call causes UI nesting bugs that are hard to trace 2. **Visual sprawl** — the begin/end pairing is separated by potentially hundreds of lines, making scope boundaries unclear ## Decision Implement a context manager suite that pairs `begin` and `end` calls on the same line using Python's `with` statement. ## Implementation ### Core Base Class ```python class ImGuiScope: def __init__(self, begin_fn, end_fn, *args, **kwargs): self._begin_fn = begin_fn self._end_fn = end_fn self._args = args self._kwargs = kwargs self._opened = None self._entered = False def __enter__(self): result = self._begin_fn(*self._args, **self._kwargs) if isinstance(result, tuple): self._opened = result[0] else: self._opened = result self._entered = bool(self._opened) return self._opened def __exit__(self, *args): if self._entered: self._end_fn() return False ``` ### Scope Helpers | Function | Wraps | Signature | |----------|-------|-----------| | `imgui_window(name, visible=True, flags=0)` | `imgui.begin` | `__enter__` returns `opened` bool | | `imgui_table(name, columns, flags=0)` | `imgui.begin_table` | `__enter__` returns `opened` bool | | `imgui_menu_bar()` | `imgui.begin_menu_bar` | No args | | `imgui_menu(label)` | `imgui.begin_menu` | `__enter__` returns `opened` bool | | `imgui_child(id, width=0, height=0, flags=0)` | `imgui.begin_child` | `__enter__` returns `opened` bool | | `imgui_group()` | `imgui.begin_group` | No args | | `imgui_popup(id)` | `imgui.begin_popup` | `__enter__` returns `opened` bool | | `imgui_tooltip()` | `imgui.begin_tooltip` | No args | | `imgui_clipper(count)` | `clipper.begin` | `__enter__` returns `opened` count | | `node_editor_scope(name)` | `ed.begin` | `__enter__` returns `opened` bool | ### Usage Pattern ```python # Before exp, opened = imgui.begin("AI Settings", self.show_windows["AI Settings"]) if exp: imgui.text("Settings") imgui.separator() # ... 50 more lines ... imgui.end() # After if imgui_window("AI Settings", self.show_windows["AI Settings"], flags): imgui.text("Settings") imgui.separator() # ... 50 more lines ... # imgui.end() called automatically ``` ## File Location `src/imgui_scopes.py` ## Migration Strategy 1. New code MUST use context managers 2. Existing code migrates incrementally during bug fixes and feature work 3. No强制性 — old `begin()`/`end()` calls remain valid ## Consequences - **Reduced** scope pairing errors - **Improved** code legibility for AI agents - **Slight** line count reduction (one `imgui.end()` line saved per scope) - **No** runtime performance impact (imperceptible nanoseconds vs C++ binding calls)