diff --git a/docs/superpowers/specs/2026-05-11-imgui-context-managers-design.md b/docs/superpowers/specs/2026-05-11-imgui-context-managers-design.md new file mode 100644 index 0000000..0acf21b --- /dev/null +++ b/docs/superpowers/specs/2026-05-11-imgui-context-managers-design.md @@ -0,0 +1,96 @@ +# 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) \ No newline at end of file