imgui_ctx.py 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888
  1. """
  2. imgui_ctx provides context managers to simplify the use of paired ImGui functions such as:
  3. 1. `imgui.begin()` / `imgui.end()`
  4. can be replaced by: `with imgui_ctx.begin() as window:` + `if window:`
  5. 2. `imgui.begin_child()` / `imgui.end_child()`
  6. can be replaced by: `with imgui_ctx.begin_child() as child:` + `if child:`
  7. 3. `imgui.begin_menu_bar()` / `imgui.end_menu_bar()`
  8. can be replaced by: `with imgui_ctx.begin_menu_bar() as menu_bar:` + `if menu_bar:`
  9. ...
  10. Note:
  11. ImGui’s "begin"/"end" functions typically return a boolean indicating whether the context is open and usable.
  12. You may (and often should) use this boolean to guard the inner code, as in the example below:
  13. ```python
  14. with imgui_ctx.begin_main_menu_bar() as menu_bar:
  15. if menu_bar:
  16. with imgui_ctx.begin_menu("Edit1") as menu_edit:
  17. if menu_edit:
  18. imgui.menu_item_simple("Undo")
  19. imgui.menu_item_simple("Redo")
  20. ```
  21. This pattern avoids rendering UI elements inside a closed or collapsed container, as per ImGui’s recommended usage.
  22. """
  23. from imgui_bundle import imgui, ImVec2, ImVec4
  24. from types import TracebackType
  25. from typing import Optional, Callable, Any, Type
  26. ChildFlags = int # see enum imgui.ChildFlags_
  27. WindowFlags = int # see enum imgui.WindowFlags_
  28. TableFlags = int # see enum imgui.TableFlags_
  29. TabBarFlags = int # see enum imgui.TabBarFlags_
  30. TabItemFlags = int # see enum imgui.TabItemFlags_
  31. DragDropFlags = int # see enum imgui.DragDropFlags_
  32. TreeNodeFlags = int # see enum imgui.TreeNodeFlags_
  33. OptExceptType = Optional[Type[BaseException]]
  34. OptBaseException = Optional[BaseException]
  35. OptTraceback = Optional[TracebackType]
  36. _EnterCallback = Callable[[], Any]
  37. IM_VEC2_ZERO = ImVec2(0.0, 0.0)
  38. class _BeginEndChild:
  39. visible: bool
  40. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  41. _enter_callback: _EnterCallback
  42. def __init__(self,
  43. str_id: str,
  44. size: ImVec2 = IM_VEC2_ZERO,
  45. child_flags: ChildFlags = 0,
  46. window_flags: WindowFlags = 0) -> None:
  47. self._enter_callback = lambda: imgui.begin_child(str_id, size, child_flags, window_flags)
  48. def __enter__(self) -> "_BeginEndChild":
  49. self.visible = self._enter_callback()
  50. return self
  51. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  52. imgui.end_child()
  53. def __bool__(self) -> bool:
  54. return self.visible
  55. def __repr__(self) -> str:
  56. return "{}(visible={})".format(
  57. self.__class__.__name__, self.visible
  58. )
  59. def __eq__(self, other: object) -> bool:
  60. if other.__class__ is self.__class__:
  61. return self.visible is other.visible
  62. return self.visible is other
  63. def begin_child(str_id: str,
  64. size: ImVec2 = IM_VEC2_ZERO,
  65. child_flags: ChildFlags = 0,
  66. window_flags: WindowFlags = 0) -> _BeginEndChild:
  67. return _BeginEndChild(str_id, size, child_flags, window_flags)
  68. class _BeginEnd:
  69. expanded: bool
  70. opened: bool
  71. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  72. _enter_callback: _EnterCallback
  73. def __init__(self, name: str, p_open: Optional[bool] = None, flags: WindowFlags = 0) -> None:
  74. self._enter_callback = lambda: imgui.begin(name, p_open, flags)
  75. def __enter__(self) -> "_BeginEnd":
  76. self.expanded, self.opened = self._enter_callback()
  77. return self
  78. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  79. imgui.end()
  80. def __bool__(self) -> bool:
  81. if self.opened is None:
  82. return self.expanded
  83. else:
  84. return self.expanded and self.opened
  85. def __getitem__(self, item: int) -> bool:
  86. return (self.expanded, self.opened)[item]
  87. def __iter__(self) -> Any:
  88. return iter((self.expanded, self.opened))
  89. def __repr__(self) -> str:
  90. return "{}(expanded={}, opened={})".format(
  91. self.__class__.__name__, self.expanded, self.opened
  92. )
  93. def __eq__(self, other: object) -> bool:
  94. if other.__class__ is self.__class__:
  95. return (self.expanded, self.opened) == (other.expanded, other.opened)
  96. return (self.expanded, self.opened) == other
  97. def begin(name: str, p_open: Optional[bool] = None, flags: WindowFlags = 0) -> _BeginEnd:
  98. r = _BeginEnd(name, p_open, flags)
  99. return r
  100. class _BeginEndListBox:
  101. opened: bool
  102. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  103. _enter_callback: _EnterCallback
  104. def __init__(self, label: str, size: ImVec2 = IM_VEC2_ZERO) -> None:
  105. self._enter_callback = lambda: imgui.begin_list_box(label, size)
  106. def __enter__(self) -> "_BeginEndListBox":
  107. self.opened = self._enter_callback()
  108. return self
  109. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  110. if self.opened: # only call end_list_box if begin_list_box was successful
  111. imgui.end_list_box()
  112. def __bool__(self) -> bool:
  113. return self.opened
  114. def __repr__(self) -> str:
  115. return "{}(opened={})".format(
  116. self.__class__.__name__, self.opened
  117. )
  118. def __eq__(self, other: object) -> bool:
  119. if other.__class__ is self.__class__:
  120. return self.opened is other.opened
  121. return self.opened is other
  122. def begin_list_box(label: str, size: ImVec2 = IM_VEC2_ZERO) -> _BeginEndListBox:
  123. return _BeginEndListBox(label, size)
  124. class _BeginEndTooltip:
  125. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  126. visible: bool
  127. _enter_callback: _EnterCallback
  128. def __init__(self) -> None:
  129. self._enter_callback = lambda: imgui.begin_tooltip()
  130. def __enter__(self) -> "_BeginEndTooltip":
  131. self.visible = self._enter_callback()
  132. return self
  133. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  134. if self.visible:
  135. imgui.end_tooltip()
  136. def __bool__(self) -> bool:
  137. return self.visible
  138. def __repr__(self) -> str:
  139. return "{}(opened={})".format(
  140. self.__class__.__name__, self.visible
  141. )
  142. def __eq__(self, other: object) -> bool:
  143. if other.__class__ is self.__class__:
  144. return self.visible is other.visible
  145. return self.visible is other
  146. def begin_tooltip() -> _BeginEndTooltip:
  147. return _BeginEndTooltip()
  148. class _BeginEndMenuMainBar:
  149. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  150. visible: bool
  151. _enter_callback: _EnterCallback
  152. def __init__(self) -> None:
  153. self._enter_callback = lambda: imgui.begin_main_menu_bar()
  154. def __enter__(self) -> "_BeginEndMenuMainBar":
  155. self.visible = self._enter_callback()
  156. return self
  157. def __exit__(self, exc_type: OptExceptType, exc_val: OptBaseException, exc_tb: OptTraceback) -> None:
  158. if self.visible:
  159. imgui.end_main_menu_bar()
  160. def __bool__(self) -> bool:
  161. return self.visible
  162. def __repr__(self) -> str:
  163. return "{}(opened={})".format(
  164. self.__class__.__name__, self.visible
  165. )
  166. def __eq__(self, other: object) -> bool:
  167. if other.__class__ is self.__class__:
  168. return self.visible is other.visible
  169. return self.visible is other
  170. def begin_main_menu_bar() -> _BeginEndMenuMainBar:
  171. return _BeginEndMenuMainBar()
  172. class _BeginEndMenuBar:
  173. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  174. visible: bool
  175. _enter_callback: _EnterCallback
  176. def __init__(self) -> None:
  177. self._enter_callback = lambda: imgui.begin_menu_bar()
  178. def __enter__(self) -> "_BeginEndMenuBar":
  179. self.visible = self._enter_callback()
  180. return self
  181. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  182. if self.visible: # only call end_list_box if begin_tooltip was successful
  183. imgui.end_menu_bar()
  184. def __bool__(self) -> bool:
  185. return self.visible
  186. def __repr__(self) -> str:
  187. return "{}(opened={})".format(
  188. self.__class__.__name__, self.visible
  189. )
  190. def __eq__(self, other: object) -> bool:
  191. if other.__class__ is self.__class__:
  192. return self.visible is other.visible
  193. return self.visible is other
  194. def begin_menu_bar() -> _BeginEndMenuBar:
  195. return _BeginEndMenuBar()
  196. class _BeginEndMenu:
  197. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  198. visible: bool
  199. _enter_callback: _EnterCallback
  200. def __init__(self, label: str, enabled: bool = True) -> None:
  201. self._enter_callback = lambda: imgui.begin_menu(label, enabled)
  202. def __enter__(self) -> "_BeginEndMenu":
  203. self.visible = self._enter_callback()
  204. return self
  205. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  206. if self.visible: # only call end_list_box if begin_tooltip was successful
  207. imgui.end_menu()
  208. def __bool__(self) -> bool:
  209. return self.visible
  210. def __repr__(self) -> str:
  211. return "{}(opened={})".format(
  212. self.__class__.__name__, self.visible
  213. )
  214. def __eq__(self, other: object) -> bool:
  215. if other.__class__ is self.__class__:
  216. return self.visible is other.visible
  217. return self.visible is other
  218. def begin_menu(label: str, enabled: bool = True) -> _BeginEndMenu:
  219. return _BeginEndMenu(label, enabled)
  220. class _BeginEndPopup:
  221. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  222. visible: bool
  223. _enter_callback: _EnterCallback
  224. def __init__(self, str_id: str, flags: WindowFlags = 0) -> None:
  225. self._enter_callback = lambda: imgui.begin_popup(str_id, flags)
  226. def __enter__(self) -> "_BeginEndPopup":
  227. self.visible = self._enter_callback()
  228. return self
  229. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  230. if self.visible: # only call end_list_box if begin_tooltip was successful
  231. imgui.end_popup()
  232. def __bool__(self) -> bool:
  233. return self.visible
  234. def __repr__(self) -> str:
  235. return "{}(opened={})".format(
  236. self.__class__.__name__, self.visible
  237. )
  238. def __eq__(self, other: object) -> bool:
  239. if other.__class__ is self.__class__:
  240. return self.visible is other.visible
  241. return self.visible is other
  242. def begin_popup(str_id: str, flags: WindowFlags = 0) -> _BeginEndPopup:
  243. return _BeginEndPopup(str_id, flags)
  244. class _BeginEndPopupModal:
  245. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  246. visible: bool
  247. _enter_callback: _EnterCallback
  248. def __init__(self, name: str, flags: WindowFlags = 0) -> None:
  249. self._enter_callback = lambda: imgui.begin_popup_modal(name, None, flags)
  250. def __enter__(self) -> "_BeginEndPopupModal":
  251. self.visible, _ = self._enter_callback()
  252. return self
  253. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  254. if self.visible: # only call end_list_box if begin_tooltip was successful
  255. imgui.end_popup()
  256. def __bool__(self) -> bool:
  257. return self.visible
  258. def __repr__(self) -> str:
  259. return "{}(opened={})".format(
  260. self.__class__.__name__, self.visible
  261. )
  262. def __eq__(self, other: object) -> bool:
  263. if other.__class__ is self.__class__:
  264. return self.visible is other.visible
  265. return self.visible is other
  266. def begin_popup_modal(name: str, flags: WindowFlags = 0) -> _BeginEndPopupModal:
  267. return _BeginEndPopupModal(name, flags)
  268. class _BeginEndTable:
  269. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  270. visible: bool
  271. _enter_callback: _EnterCallback
  272. def __init__(self,
  273. str_id: str,
  274. column: int,
  275. flags: TableFlags = 0,
  276. outer_size: ImVec2 = IM_VEC2_ZERO,
  277. inner_width: float = 0.0) -> None:
  278. self._enter_callback = lambda: imgui.begin_table(str_id, column, flags, outer_size, inner_width)
  279. def __enter__(self) -> "_BeginEndTable":
  280. self.visible = self._enter_callback()
  281. return self
  282. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  283. if self.visible: # only call end_list_box if begin_tooltip was successful
  284. imgui.end_table()
  285. def __bool__(self) -> bool:
  286. return self.visible
  287. def __repr__(self) -> str:
  288. return "{}(opened={})".format(
  289. self.__class__.__name__, self.visible
  290. )
  291. def __eq__(self, other: object) -> bool:
  292. if other.__class__ is self.__class__:
  293. return self.visible is other.visible
  294. return self.visible is other
  295. def begin_table(str_id: str,
  296. column: int,
  297. flags: TableFlags = 0,
  298. outer_size: ImVec2 = IM_VEC2_ZERO,
  299. inner_width: float = 0.0) -> _BeginEndTable:
  300. return _BeginEndTable(str_id, column, flags, outer_size, inner_width)
  301. class _BeginEndTabBar:
  302. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  303. visible: bool
  304. _enter_callback: _EnterCallback
  305. def __init__(self, str_id: str, flags: TabBarFlags = 0) -> None:
  306. self._enter_callback = lambda: imgui.begin_tab_bar(str_id, flags)
  307. def __enter__(self) -> "_BeginEndTabBar":
  308. self.visible = self._enter_callback()
  309. return self
  310. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  311. if self.visible: # only call end_list_box if begin_tooltip was successful
  312. imgui.end_tab_bar()
  313. def __bool__(self) -> bool:
  314. return self.visible
  315. def __repr__(self) -> str:
  316. return "{}(opened={})".format(
  317. self.__class__.__name__, self.visible
  318. )
  319. def __eq__(self, other: object) -> bool:
  320. if other.__class__ is self.__class__:
  321. return self.visible is other.visible
  322. return self.visible is other
  323. def begin_tab_bar(str_id: str, flags: TabBarFlags = 0) -> _BeginEndTabBar:
  324. return _BeginEndTabBar(str_id, flags)
  325. class _BeginEndTabItem:
  326. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  327. visible: bool
  328. _enter_callback: _EnterCallback
  329. def __init__(self, label: str, flags: TabItemFlags = 0) -> None:
  330. self._enter_callback = lambda: imgui.begin_tab_item(label, None, flags)
  331. def __enter__(self) -> "_BeginEndTabItem":
  332. self.visible, _ = self._enter_callback()
  333. return self
  334. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  335. if self.visible:
  336. imgui.end_tab_item()
  337. def __bool__(self) -> bool:
  338. return self.visible
  339. def __repr__(self) -> str:
  340. return "{}(opened={})".format(
  341. self.__class__.__name__, self.visible
  342. )
  343. def __eq__(self, other: object) -> bool:
  344. if other.__class__ is self.__class__:
  345. return self.visible is other.visible
  346. return self.visible is other
  347. def begin_tab_item(label: str, flags: TabItemFlags = 0) -> _BeginEndTabItem:
  348. return _BeginEndTabItem(label, flags)
  349. class _BeginEndDragDropSource:
  350. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  351. is_dragging: bool
  352. _enter_callback: _EnterCallback
  353. def __init__(self, flags: DragDropFlags = 0) -> None:
  354. self._enter_callback = lambda: imgui.begin_drag_drop_source(flags)
  355. def __enter__(self) -> "_BeginEndDragDropSource":
  356. self.is_dragging = self._enter_callback()
  357. return self
  358. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  359. if self.is_dragging:
  360. imgui.end_drag_drop_source()
  361. def __bool__(self) -> bool:
  362. return self.is_dragging
  363. def __repr__(self) -> str:
  364. return "{}(opened={})".format(
  365. self.__class__.__name__, self.is_dragging
  366. )
  367. def __eq__(self, other: object) -> bool:
  368. if other.__class__ is self.__class__:
  369. return self.is_dragging is other.is_dragging
  370. return self.is_dragging is other
  371. def begin_drag_drop_source(flags: DragDropFlags = 0) -> _BeginEndDragDropSource:
  372. return _BeginEndDragDropSource(flags)
  373. class _BeginEndDragDropTarget:
  374. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  375. is_receiving: bool
  376. _enter_callback: _EnterCallback
  377. def __init__(self) -> None:
  378. self._enter_callback = lambda: imgui.begin_drag_drop_target()
  379. def __enter__(self) -> "_BeginEndDragDropTarget":
  380. self.is_receiving = self._enter_callback()
  381. return self
  382. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  383. if self.is_receiving:
  384. imgui.end_drag_drop_target()
  385. def __bool__(self) -> bool:
  386. return self.is_receiving
  387. def __repr__(self) -> str:
  388. return "{}(opened={})".format(
  389. self.__class__.__name__, self.is_receiving
  390. )
  391. def __eq__(self, other: object) -> bool:
  392. if other.__class__ is self.__class__:
  393. return self.is_receiving is other.is_receiving
  394. return self.is_receiving is other
  395. def begin_drag_drop_target() -> _BeginEndDragDropTarget:
  396. return _BeginEndDragDropTarget()
  397. class _BeginEndGroup:
  398. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  399. _enter_callback: _EnterCallback
  400. def __init__(self) -> None:
  401. self._enter_callback = lambda: imgui.begin_group()
  402. def __enter__(self) -> "_BeginEndGroup":
  403. self._enter_callback()
  404. return self
  405. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  406. imgui.end_group()
  407. def __repr__(self) -> str:
  408. return "{}".format(self.__class__.__name__)
  409. def begin_group() -> _BeginEndGroup:
  410. return _BeginEndGroup()
  411. class _BeginHorizontal:
  412. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  413. _enter_callback: _EnterCallback
  414. def __init__(self, str_id: str, size: ImVec2 | None = None, align: float = -1.0) -> None:
  415. if size is None:
  416. size = ImVec2(0, 0)
  417. self._enter_callback = lambda: imgui.begin_horizontal(str_id, size, align)
  418. def __enter__(self) -> "_BeginHorizontal":
  419. self._enter_callback()
  420. return self
  421. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  422. imgui.end_horizontal()
  423. def __repr__(self) -> str:
  424. return "{}".format(self.__class__.__name__)
  425. def begin_horizontal(str_id: str, size: ImVec2 | None = None, align: float = -1.0) -> _BeginHorizontal:
  426. return _BeginHorizontal(str_id, size, align)
  427. class _BeginVertical:
  428. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  429. _enter_callback: _EnterCallback
  430. def __init__(self, str_id: str, size: ImVec2 | None = None, align: float = -1.0) -> None:
  431. if size is None:
  432. size = ImVec2(0, 0)
  433. self._enter_callback = lambda: imgui.begin_vertical(str_id, size, align)
  434. def __enter__(self) -> "_BeginVertical":
  435. self._enter_callback()
  436. return self
  437. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  438. imgui.end_vertical()
  439. def __repr__(self) -> str:
  440. return "{}".format(self.__class__.__name__)
  441. def begin_vertical(str_id: str, size: ImVec2 | None = None, align: float = -1.0) -> _BeginVertical:
  442. return _BeginVertical(str_id, size, align)
  443. class _WithTreeNode:
  444. # _enter_callback will be called in __enter__. Captures all __init__ arguments.
  445. visible: bool
  446. _enter_callback: _EnterCallback
  447. def __init__(self, label: str) -> None:
  448. self._enter_callback = lambda: imgui.tree_node(label)
  449. def __enter__(self) -> "_WithTreeNode":
  450. self.visible = self._enter_callback()
  451. return self
  452. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  453. if self.visible:
  454. imgui.tree_pop()
  455. def __bool__(self) -> bool:
  456. return self.visible
  457. def __repr__(self) -> str:
  458. return "{}(opened={})".format(
  459. self.__class__.__name__, self.visible
  460. )
  461. def __eq__(self, other: object) -> bool:
  462. if other.__class__ is self.__class__:
  463. return self.visible is other.visible
  464. return self.visible is other
  465. def tree_node(label: str) -> _WithTreeNode:
  466. return _WithTreeNode(label)
  467. class _WithTreeNodeEx:
  468. visible: bool
  469. _enter_callback: _EnterCallback
  470. def __init__(self, label: str, flags: TreeNodeFlags = 0) -> None:
  471. self._enter_callback = lambda: imgui.tree_node_ex(label, flags)
  472. def __enter__(self) -> "_WithTreeNodeEx":
  473. self.visible = self._enter_callback()
  474. return self
  475. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  476. if self.visible:
  477. imgui.tree_pop()
  478. def __bool__(self) -> bool:
  479. return self.visible
  480. def __repr__(self) -> str:
  481. return "{}(opened={})".format(
  482. self.__class__.__qualname__, self.visible
  483. )
  484. def __eq__(self, other: object) -> bool:
  485. if other.__class__ is self.__class__:
  486. return self.visible is other.visible
  487. return self.visible is other
  488. def tree_node_ex(label: str, flags: TreeNodeFlags = 0) -> _WithTreeNodeEx:
  489. return _WithTreeNodeEx(label, flags)
  490. class _WithPushID:
  491. _enter_callback: _EnterCallback
  492. def __init__(self, str_id: str) -> None:
  493. self._enter_callback = lambda: imgui.push_id(str_id)
  494. def __enter__(self) -> "_WithPushID":
  495. self._enter_callback()
  496. return self
  497. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  498. imgui.pop_id()
  499. def __repr__(self) -> str:
  500. return self.__class__.__name__
  501. def push_id(str_id: str) -> _WithPushID:
  502. return _WithPushID(str_id)
  503. def push_obj_id(obj: Any) -> _WithPushID:
  504. return _WithPushID(str(id(obj)))
  505. class _WithPushFont:
  506. _enter_callback: _EnterCallback
  507. def __init__(self, font: imgui.ImFont, font_size_base_unscaled: float = 0.0) -> None:
  508. self._enter_callback = lambda: imgui.push_font(font, font_size_base_unscaled)
  509. def __enter__(self) -> "_WithPushFont":
  510. self._enter_callback()
  511. return self
  512. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  513. imgui.pop_font()
  514. def __repr__(self) -> str:
  515. return self.__class__.__name__
  516. def push_font(font: imgui.ImFont) -> _WithPushFont:
  517. return _WithPushFont(font)
  518. class _WithPushStyleColor:
  519. _enter_callback: _EnterCallback
  520. def __init__(self, idx: int, col: ImVec4) -> None:
  521. self._enter_callback = lambda: imgui.push_style_color(idx, col)
  522. def __enter__(self) -> "_WithPushStyleColor":
  523. self._enter_callback()
  524. return self
  525. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  526. imgui.pop_style_color()
  527. def __repr__(self) -> str:
  528. return self.__class__.__name__
  529. def push_style_color(idx: int, col: ImVec4) -> _WithPushStyleColor:
  530. return _WithPushStyleColor(idx, col)
  531. class _WithPushStyleVar:
  532. _enter_callback: _EnterCallback
  533. def __init__(self, idx: int, val: Any) -> None:
  534. self._enter_callback = lambda: imgui.push_style_var(idx, val)
  535. def __enter__(self) -> "_WithPushStyleVar":
  536. self._enter_callback()
  537. return self
  538. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  539. imgui.pop_style_var()
  540. def __repr__(self) -> str:
  541. return self.__class__.__name__
  542. def push_style_var(idx: int, val: Any) -> _WithPushStyleVar:
  543. return _WithPushStyleVar(idx, val)
  544. class _WithPushItemWidth:
  545. _enter_callback: _EnterCallback
  546. def __init__(self, item_width: float) -> None:
  547. self._enter_callback = lambda: imgui.push_item_width(item_width)
  548. def __enter__(self) -> "_WithPushItemWidth":
  549. self._enter_callback()
  550. return self
  551. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  552. imgui.pop_item_width()
  553. def __repr__(self) -> str:
  554. return self.__class__.__name__
  555. def push_item_width(item_width: float) -> _WithPushItemWidth:
  556. return _WithPushItemWidth(item_width)
  557. class _WithPushTextWrapPos:
  558. _enter_callback: _EnterCallback
  559. def __init__(self, wrap_pos_x: float = 0.0) -> None:
  560. self._enter_callback = lambda: imgui.push_text_wrap_pos(wrap_pos_x)
  561. def __enter__(self) -> "_WithPushTextWrapPos":
  562. self._enter_callback()
  563. return self
  564. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  565. imgui.pop_text_wrap_pos()
  566. def __repr__(self) -> str:
  567. return self.__class__.__name__
  568. def push_text_wrap_pos(wrap_pos_x: float = 0.0) -> _WithPushTextWrapPos:
  569. return _WithPushTextWrapPos(wrap_pos_x)
  570. class _WithPushButtonRepeat:
  571. _enter_callback: _EnterCallback
  572. def __init__(self, repeat: bool = True) -> None:
  573. self._enter_callback = lambda: imgui.push_item_flag(imgui.ItemFlags_.button_repeat.value, True)
  574. def __enter__(self) -> "_WithPushButtonRepeat":
  575. self._enter_callback()
  576. return self
  577. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  578. imgui.pop_item_flag()
  579. def __repr__(self) -> str:
  580. return self.__class__.__name__
  581. def push_button_repeat(repeat: bool = True) -> _WithPushButtonRepeat:
  582. return _WithPushButtonRepeat(repeat)
  583. class _WithPushClipRect:
  584. _enter_callback: _EnterCallback
  585. def __init__(self, clip_rect_min: ImVec2, clip_rect_max: ImVec2, intersect_with_current_clip_rect: bool) -> None:
  586. self._enter_callback = lambda: imgui.push_clip_rect(
  587. clip_rect_min, clip_rect_max, intersect_with_current_clip_rect)
  588. def __enter__(self) -> "_WithPushClipRect":
  589. self._enter_callback()
  590. return self
  591. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  592. imgui.pop_clip_rect()
  593. def __repr__(self) -> str:
  594. return self.__class__.__name__
  595. def push_clip_rect(
  596. clip_rect_min: ImVec2,
  597. clip_rect_max: ImVec2,
  598. intersect_with_current_clip_rect: bool
  599. ) -> _WithPushClipRect:
  600. return _WithPushClipRect(clip_rect_min, clip_rect_max, intersect_with_current_clip_rect)
  601. class _WithPushTabStop:
  602. _enter_callback: _EnterCallback
  603. def __init__(self, tab_stop: bool) -> None:
  604. self._enter_callback = lambda: imgui.push_tab_stop(tab_stop)
  605. def __enter__(self) -> "_WithPushTabStop":
  606. self._enter_callback()
  607. return self
  608. def __exit__(self, _exc_type: OptExceptType, _exc_val: OptBaseException, _exc_tb: OptTraceback) -> None:
  609. imgui.pop_tab_stop()
  610. def __repr__(self) -> str:
  611. return self.__class__.__name__
  612. def push_tab_stop(tab_stop: bool) -> _WithPushTabStop:
  613. return _WithPushTabStop(tab_stop)