# 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)