3.1 KiB
3.1 KiB
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:
- Error-prone for AI agents — forgetting an
end()call causes UI nesting bugs that are hard to trace - 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
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
# 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
- New code MUST use context managers
- Existing code migrates incrementally during bug fixes and feature work
- 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)