wxPython 4.3.2__cp315-cp315-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. wx/WebView2Loader.dll +0 -0
  2. wx/__init__.py +22 -0
  3. wx/__init__.pyi +10 -0
  4. wx/__version__.py +9 -0
  5. wx/__version__.pyi +15 -0
  6. wx/_adv.cp315-win_amd64.pyd +0 -0
  7. wx/_aui.cp315-win_amd64.pyd +0 -0
  8. wx/_core.cp315-win_amd64.pyd +0 -0
  9. wx/_dataview.cp315-win_amd64.pyd +0 -0
  10. wx/_glcanvas.cp315-win_amd64.pyd +0 -0
  11. wx/_grid.cp315-win_amd64.pyd +0 -0
  12. wx/_html.cp315-win_amd64.pyd +0 -0
  13. wx/_html2.cp315-win_amd64.pyd +0 -0
  14. wx/_media.cp315-win_amd64.pyd +0 -0
  15. wx/_msw.cp315-win_amd64.pyd +0 -0
  16. wx/_propgrid.cp315-win_amd64.pyd +0 -0
  17. wx/_ribbon.cp315-win_amd64.pyd +0 -0
  18. wx/_richtext.cp315-win_amd64.pyd +0 -0
  19. wx/_stc.cp315-win_amd64.pyd +0 -0
  20. wx/_xml.cp315-win_amd64.pyd +0 -0
  21. wx/_xrc.cp315-win_amd64.pyd +0 -0
  22. wx/adv.py +127 -0
  23. wx/adv.pyi +5931 -0
  24. wx/aui.py +70 -0
  25. wx/aui.pyi +4805 -0
  26. wx/core.py +3417 -0
  27. wx/core.pyi +62949 -0
  28. wx/dataview.py +176 -0
  29. wx/dataview.pyi +3828 -0
  30. wx/gizmos.py +18 -0
  31. wx/glcanvas.py +13 -0
  32. wx/glcanvas.pyi +544 -0
  33. wx/grid.py +237 -0
  34. wx/grid.pyi +5678 -0
  35. wx/html.py +38 -0
  36. wx/html.pyi +3283 -0
  37. wx/html2.py +46 -0
  38. wx/html2.pyi +1301 -0
  39. wx/include/wxPython/sip.h +1938 -0
  40. wx/include/wxPython/wxpy_api.h +418 -0
  41. wx/lib/CDate.py +201 -0
  42. wx/lib/ClickableHtmlWindow.py +57 -0
  43. wx/lib/__init__.py +0 -0
  44. wx/lib/activex.py +178 -0
  45. wx/lib/activexwrapper.py +153 -0
  46. wx/lib/agw/__init__.py +128 -0
  47. wx/lib/agw/advancedsplash.py +563 -0
  48. wx/lib/agw/aquabutton.py +1127 -0
  49. wx/lib/agw/artmanager.py +2110 -0
  50. wx/lib/agw/aui/__init__.py +295 -0
  51. wx/lib/agw/aui/aui_constants.py +2616 -0
  52. wx/lib/agw/aui/aui_switcherdialog.py +1232 -0
  53. wx/lib/agw/aui/aui_utilities.py +648 -0
  54. wx/lib/agw/aui/auibar.py +4045 -0
  55. wx/lib/agw/aui/auibook.py +6288 -0
  56. wx/lib/agw/aui/dockart.py +1198 -0
  57. wx/lib/agw/aui/framemanager.py +10485 -0
  58. wx/lib/agw/aui/tabart.py +2749 -0
  59. wx/lib/agw/aui/tabmdi.py +679 -0
  60. wx/lib/agw/balloontip.py +1157 -0
  61. wx/lib/agw/buttonpanel.py +2787 -0
  62. wx/lib/agw/cubecolourdialog.py +3529 -0
  63. wx/lib/agw/customtreectrl.py +9908 -0
  64. wx/lib/agw/data/ShortcutEditor_1.png +0 -0
  65. wx/lib/agw/data/ShortcutEditor_1_thumb.png +0 -0
  66. wx/lib/agw/data/ShortcutEditor_2.png +0 -0
  67. wx/lib/agw/data/ShortcutEditor_2_thumb.png +0 -0
  68. wx/lib/agw/data/ShortcutEditor_3.png +0 -0
  69. wx/lib/agw/data/ShortcutEditor_3_thumb.png +0 -0
  70. wx/lib/agw/data/ShortcutEditor_4.png +0 -0
  71. wx/lib/agw/data/ShortcutEditor_4_thumb.png +0 -0
  72. wx/lib/agw/data/default_help_text.html +105 -0
  73. wx/lib/agw/flatmenu.py +7392 -0
  74. wx/lib/agw/flatnotebook.py +6669 -0
  75. wx/lib/agw/floatspin.py +1820 -0
  76. wx/lib/agw/fmcustomizedlg.py +535 -0
  77. wx/lib/agw/fmresources.py +407 -0
  78. wx/lib/agw/foldpanelbar.py +2282 -0
  79. wx/lib/agw/fourwaysplitter.py +1130 -0
  80. wx/lib/agw/genericmessagedialog.py +1549 -0
  81. wx/lib/agw/gradientbutton.py +731 -0
  82. wx/lib/agw/hyperlink.py +664 -0
  83. wx/lib/agw/hypertreelist.py +5756 -0
  84. wx/lib/agw/infobar.py +885 -0
  85. wx/lib/agw/knobctrl.py +944 -0
  86. wx/lib/agw/labelbook.py +3028 -0
  87. wx/lib/agw/multidirdialog.py +581 -0
  88. wx/lib/agw/peakmeter.py +1028 -0
  89. wx/lib/agw/persist/__init__.py +188 -0
  90. wx/lib/agw/persist/persist_constants.py +283 -0
  91. wx/lib/agw/persist/persist_handlers.py +2614 -0
  92. wx/lib/agw/persist/persistencemanager.py +863 -0
  93. wx/lib/agw/piectrl.py +1082 -0
  94. wx/lib/agw/pybusyinfo.py +399 -0
  95. wx/lib/agw/pycollapsiblepane.py +940 -0
  96. wx/lib/agw/pygauge.py +570 -0
  97. wx/lib/agw/pyprogress.py +916 -0
  98. wx/lib/agw/ribbon/__init__.py +198 -0
  99. wx/lib/agw/ribbon/art.py +219 -0
  100. wx/lib/agw/ribbon/art_aui.py +1283 -0
  101. wx/lib/agw/ribbon/art_default.py +81 -0
  102. wx/lib/agw/ribbon/art_internal.py +248 -0
  103. wx/lib/agw/ribbon/art_msw.py +2735 -0
  104. wx/lib/agw/ribbon/art_osx.py +52 -0
  105. wx/lib/agw/ribbon/bar.py +1259 -0
  106. wx/lib/agw/ribbon/buttonbar.py +1317 -0
  107. wx/lib/agw/ribbon/control.py +205 -0
  108. wx/lib/agw/ribbon/gallery.py +973 -0
  109. wx/lib/agw/ribbon/page.py +946 -0
  110. wx/lib/agw/ribbon/panel.py +1170 -0
  111. wx/lib/agw/ribbon/toolbar.py +1441 -0
  112. wx/lib/agw/rulerctrl.py +1885 -0
  113. wx/lib/agw/scrolledthumbnail.py +2116 -0
  114. wx/lib/agw/shapedbutton.py +1809 -0
  115. wx/lib/agw/shortcuteditor.py +2642 -0
  116. wx/lib/agw/speedmeter.py +1800 -0
  117. wx/lib/agw/supertooltip.py +1443 -0
  118. wx/lib/agw/thumbnailctrl.py +529 -0
  119. wx/lib/agw/toasterbox.py +1327 -0
  120. wx/lib/agw/ultimatelistctrl.py +13671 -0
  121. wx/lib/agw/xlsgrid.py +2111 -0
  122. wx/lib/agw/zoombar.py +1336 -0
  123. wx/lib/analogclock/__init__.py +140 -0
  124. wx/lib/analogclock/analogclock.py +630 -0
  125. wx/lib/analogclock/helpers.py +986 -0
  126. wx/lib/analogclock/lib_setup/__init__.py +0 -0
  127. wx/lib/analogclock/lib_setup/buttontreectrlpanel.py +297 -0
  128. wx/lib/analogclock/lib_setup/fontselect.py +57 -0
  129. wx/lib/analogclock/setup.py +490 -0
  130. wx/lib/analogclock/styles.py +47 -0
  131. wx/lib/anchors.py +103 -0
  132. wx/lib/art/__init__.py +4 -0
  133. wx/lib/art/flagart.py +1583 -0
  134. wx/lib/art/img2pyartprov.py +56 -0
  135. wx/lib/busy.py +152 -0
  136. wx/lib/buttons.py +1140 -0
  137. wx/lib/calendar.py +1596 -0
  138. wx/lib/checkbox.py +837 -0
  139. wx/lib/colourchooser/__init__.py +36 -0
  140. wx/lib/colourchooser/canvas.py +145 -0
  141. wx/lib/colourchooser/intl.py +24 -0
  142. wx/lib/colourchooser/pycolourbox.py +89 -0
  143. wx/lib/colourchooser/pycolourchooser.py +626 -0
  144. wx/lib/colourchooser/pycolourslider.py +98 -0
  145. wx/lib/colourchooser/pypalette.py +208 -0
  146. wx/lib/colourdb.py +740 -0
  147. wx/lib/colourselect.py +385 -0
  148. wx/lib/colourutils.py +118 -0
  149. wx/lib/combotreebox.py +944 -0
  150. wx/lib/delayedresult.py +420 -0
  151. wx/lib/dialogs.py +510 -0
  152. wx/lib/docview.py +3210 -0
  153. wx/lib/dragscroller.py +79 -0
  154. wx/lib/editor/README.txt +77 -0
  155. wx/lib/editor/__init__.py +24 -0
  156. wx/lib/editor/editor.py +974 -0
  157. wx/lib/editor/images.py +15 -0
  158. wx/lib/editor/selection.py +44 -0
  159. wx/lib/embeddedimage.py +76 -0
  160. wx/lib/eventStack.py +136 -0
  161. wx/lib/eventwatcher.py +440 -0
  162. wx/lib/evtmgr.py +521 -0
  163. wx/lib/expando.py +393 -0
  164. wx/lib/fancytext.py +494 -0
  165. wx/lib/filebrowsebutton.py +461 -0
  166. wx/lib/flashwin.py +262 -0
  167. wx/lib/flashwin_old.py +651 -0
  168. wx/lib/floatcanvas/FCEvents.py +53 -0
  169. wx/lib/floatcanvas/FCObjects.py +2910 -0
  170. wx/lib/floatcanvas/FloatCanvas.py +1025 -0
  171. wx/lib/floatcanvas/GUIMode.py +396 -0
  172. wx/lib/floatcanvas/NavCanvas.py +162 -0
  173. wx/lib/floatcanvas/Resources.py +319 -0
  174. wx/lib/floatcanvas/ScreenShot.py +1788 -0
  175. wx/lib/floatcanvas/Utilities/BBox.py +313 -0
  176. wx/lib/floatcanvas/Utilities/Colors.py +137 -0
  177. wx/lib/floatcanvas/Utilities/GUI.py +91 -0
  178. wx/lib/floatcanvas/Utilities/__init__.py +7 -0
  179. wx/lib/floatcanvas/__init__.py +124 -0
  180. wx/lib/foldmenu.py +89 -0
  181. wx/lib/gestures.py +310 -0
  182. wx/lib/gizmos/__init__.py +18 -0
  183. wx/lib/gizmos/dynamicsash.py +1202 -0
  184. wx/lib/gizmos/ledctrl.py +299 -0
  185. wx/lib/gizmos/treelistctrl.py +87 -0
  186. wx/lib/graphics.py +1942 -0
  187. wx/lib/gridmovers.py +516 -0
  188. wx/lib/iewin.py +249 -0
  189. wx/lib/iewin_old.py +894 -0
  190. wx/lib/imagebrowser.py +853 -0
  191. wx/lib/imageutils.py +163 -0
  192. wx/lib/infoframe.py +490 -0
  193. wx/lib/inspection.py +1254 -0
  194. wx/lib/intctrl.py +990 -0
  195. wx/lib/itemspicker.py +256 -0
  196. wx/lib/langlistctrl.py +480 -0
  197. wx/lib/layoutf.py +271 -0
  198. wx/lib/masked/__init__.py +27 -0
  199. wx/lib/masked/combobox.py +839 -0
  200. wx/lib/masked/ctrl.py +108 -0
  201. wx/lib/masked/ipaddrctrl.py +241 -0
  202. wx/lib/masked/maskededit.py +7262 -0
  203. wx/lib/masked/numctrl.py +2000 -0
  204. wx/lib/masked/textctrl.py +465 -0
  205. wx/lib/masked/timectrl.py +1465 -0
  206. wx/lib/mixins/__init__.py +17 -0
  207. wx/lib/mixins/grid.py +47 -0
  208. wx/lib/mixins/gridlabelrenderer.py +277 -0
  209. wx/lib/mixins/imagelist.py +77 -0
  210. wx/lib/mixins/inspection.py +184 -0
  211. wx/lib/mixins/listctrl.py +893 -0
  212. wx/lib/mixins/rubberband.py +403 -0
  213. wx/lib/mixins/treemixin.py +678 -0
  214. wx/lib/msgpanel.py +95 -0
  215. wx/lib/multisash.py +746 -0
  216. wx/lib/myole4ax.idl +178 -0
  217. wx/lib/myole4ax.tlb +0 -0
  218. wx/lib/newevent.py +229 -0
  219. wx/lib/newevent.pyi +25 -0
  220. wx/lib/nvdlg.py +156 -0
  221. wx/lib/ogl/__init__.py +13 -0
  222. wx/lib/ogl/basic.py +3989 -0
  223. wx/lib/ogl/bmpshape.py +86 -0
  224. wx/lib/ogl/canvas.py +467 -0
  225. wx/lib/ogl/composit.py +1576 -0
  226. wx/lib/ogl/diagram.py +230 -0
  227. wx/lib/ogl/divided.py +482 -0
  228. wx/lib/ogl/drawn.py +898 -0
  229. wx/lib/ogl/lines.py +1809 -0
  230. wx/lib/ogl/oglmisc.py +607 -0
  231. wx/lib/pdfviewer/__init__.py +113 -0
  232. wx/lib/pdfviewer/bitmaps/ArrowLeft.png +0 -0
  233. wx/lib/pdfviewer/bitmaps/ArrowRight.png +0 -0
  234. wx/lib/pdfviewer/bitmaps/DirectionH.png +0 -0
  235. wx/lib/pdfviewer/bitmaps/DirectionV.png +0 -0
  236. wx/lib/pdfviewer/bitmaps/PlayerFirst.png +0 -0
  237. wx/lib/pdfviewer/bitmaps/PlayerLast.png +0 -0
  238. wx/lib/pdfviewer/bitmaps/PlayerNext.png +0 -0
  239. wx/lib/pdfviewer/bitmaps/PlayerPrev.png +0 -0
  240. wx/lib/pdfviewer/bitmaps/Printer.png +0 -0
  241. wx/lib/pdfviewer/bitmaps/ReadMe.txt +28 -0
  242. wx/lib/pdfviewer/bitmaps/Save.png +0 -0
  243. wx/lib/pdfviewer/bitmaps/ZoomIn.png +0 -0
  244. wx/lib/pdfviewer/bitmaps/ZoomOut.png +0 -0
  245. wx/lib/pdfviewer/bitmaps/encode_bitmaps.py +37 -0
  246. wx/lib/pdfviewer/buttonpanel.py +285 -0
  247. wx/lib/pdfviewer/images.py +240 -0
  248. wx/lib/pdfviewer/viewer.py +1118 -0
  249. wx/lib/pdfwin.py +295 -0
  250. wx/lib/pdfwin_old.py +789 -0
  251. wx/lib/platebtn.py +789 -0
  252. wx/lib/plot/CHANGELOG.md +150 -0
  253. wx/lib/plot/README.md +16 -0
  254. wx/lib/plot/__init__.py +46 -0
  255. wx/lib/plot/__main__.py +5 -0
  256. wx/lib/plot/examples/__init__.py +0 -0
  257. wx/lib/plot/examples/demo.py +1010 -0
  258. wx/lib/plot/examples/simple_example.py +56 -0
  259. wx/lib/plot/plotcanvas.py +2985 -0
  260. wx/lib/plot/polyobjects.py +1524 -0
  261. wx/lib/plot/utils.py +334 -0
  262. wx/lib/popupctl.py +251 -0
  263. wx/lib/printout.py +1155 -0
  264. wx/lib/progressindicator.py +151 -0
  265. wx/lib/pubsub/LICENSE_BSD_Simple.txt +23 -0
  266. wx/lib/pubsub/README_WxPython.txt +22 -0
  267. wx/lib/pubsub/RELEASE_NOTES.txt +71 -0
  268. wx/lib/pubsub/__init__.py +25 -0
  269. wx/lib/pubsub/core/__init__.py +92 -0
  270. wx/lib/pubsub/core/arg1/__init__.py +16 -0
  271. wx/lib/pubsub/core/arg1/listenerimpl.py +97 -0
  272. wx/lib/pubsub/core/arg1/publisher.py +40 -0
  273. wx/lib/pubsub/core/arg1/publishermixin.py +34 -0
  274. wx/lib/pubsub/core/arg1/topicargspecimpl.py +66 -0
  275. wx/lib/pubsub/core/arg1/topicmgrimpl.py +19 -0
  276. wx/lib/pubsub/core/callables.py +198 -0
  277. wx/lib/pubsub/core/imp2.py +62 -0
  278. wx/lib/pubsub/core/itopicdefnprovider.py +0 -0
  279. wx/lib/pubsub/core/kwargs/__init__.py +16 -0
  280. wx/lib/pubsub/core/kwargs/datamsg.py +27 -0
  281. wx/lib/pubsub/core/kwargs/listenerimpl.py +93 -0
  282. wx/lib/pubsub/core/kwargs/publisher.py +77 -0
  283. wx/lib/pubsub/core/kwargs/publishermixin.py +65 -0
  284. wx/lib/pubsub/core/kwargs/topicargspecimpl.py +216 -0
  285. wx/lib/pubsub/core/kwargs/topicmgrimpl.py +13 -0
  286. wx/lib/pubsub/core/listener.py +40 -0
  287. wx/lib/pubsub/core/listenerbase.py +185 -0
  288. wx/lib/pubsub/core/notificationmgr.py +185 -0
  289. wx/lib/pubsub/core/publisherbase.py +189 -0
  290. wx/lib/pubsub/core/topicargspec.py +77 -0
  291. wx/lib/pubsub/core/topicdefnprovider.py +631 -0
  292. wx/lib/pubsub/core/topicexc.py +72 -0
  293. wx/lib/pubsub/core/topicmgr.py +454 -0
  294. wx/lib/pubsub/core/topicobj.py +472 -0
  295. wx/lib/pubsub/core/topictreetraverser.py +143 -0
  296. wx/lib/pubsub/core/topicutils.py +119 -0
  297. wx/lib/pubsub/core/treeconfig.py +21 -0
  298. wx/lib/pubsub/core/validatedefnargs.py +29 -0
  299. wx/lib/pubsub/core/weakmethod.py +102 -0
  300. wx/lib/pubsub/policies.py +24 -0
  301. wx/lib/pubsub/pub.py +199 -0
  302. wx/lib/pubsub/setuparg1.py +47 -0
  303. wx/lib/pubsub/setupkwargs.py +29 -0
  304. wx/lib/pubsub/utils/__init__.py +27 -0
  305. wx/lib/pubsub/utils/exchandling.py +100 -0
  306. wx/lib/pubsub/utils/misc.py +99 -0
  307. wx/lib/pubsub/utils/notification.py +331 -0
  308. wx/lib/pubsub/utils/topictreeprinter.py +195 -0
  309. wx/lib/pubsub/utils/xmltopicdefnprovider.py +286 -0
  310. wx/lib/pydocview.py +3300 -0
  311. wx/lib/rcsizer.py +227 -0
  312. wx/lib/resizewidget.py +357 -0
  313. wx/lib/scrolledpanel.py +243 -0
  314. wx/lib/sheet.py +350 -0
  315. wx/lib/sized_controls.py +691 -0
  316. wx/lib/softwareupdate.py +355 -0
  317. wx/lib/splitter.py +925 -0
  318. wx/lib/statbmp.py +199 -0
  319. wx/lib/stattext.py +321 -0
  320. wx/lib/throbber.py +424 -0
  321. wx/lib/ticker.py +306 -0
  322. wx/lib/ticker_xrc.py +48 -0
  323. wx/lib/utils.py +89 -0
  324. wx/lib/wordwrap.py +97 -0
  325. wx/lib/wxcairo/__init__.py +139 -0
  326. wx/lib/wxcairo/wx_cairocffi.py +200 -0
  327. wx/lib/wxcairo/wx_pycairo.py +455 -0
  328. wx/lib/wxpTag.py +274 -0
  329. wx/libcairo-2.dll +0 -0
  330. wx/locale/af/LC_MESSAGES/wxstd.mo +0 -0
  331. wx/locale/an/LC_MESSAGES/wxstd.mo +0 -0
  332. wx/locale/ar/LC_MESSAGES/wxstd.mo +0 -0
  333. wx/locale/ca/LC_MESSAGES/wxstd.mo +0 -0
  334. wx/locale/ca@valencia/LC_MESSAGES/wxstd.mo +0 -0
  335. wx/locale/co/LC_MESSAGES/wxstd.mo +0 -0
  336. wx/locale/cs/LC_MESSAGES/wxstd.mo +0 -0
  337. wx/locale/da/LC_MESSAGES/wxstd.mo +0 -0
  338. wx/locale/de/LC_MESSAGES/wxstd.mo +0 -0
  339. wx/locale/el/LC_MESSAGES/wxstd.mo +0 -0
  340. wx/locale/es/LC_MESSAGES/wxstd.mo +0 -0
  341. wx/locale/eu/LC_MESSAGES/wxstd.mo +0 -0
  342. wx/locale/fa_IR/LC_MESSAGES/wxstd.mo +0 -0
  343. wx/locale/fi/LC_MESSAGES/wxstd.mo +0 -0
  344. wx/locale/fr/LC_MESSAGES/wxstd.mo +0 -0
  345. wx/locale/gl_ES/LC_MESSAGES/wxstd.mo +0 -0
  346. wx/locale/hi/LC_MESSAGES/wxstd.mo +0 -0
  347. wx/locale/hr/LC_MESSAGES/wxstd.mo +0 -0
  348. wx/locale/hu/LC_MESSAGES/wxstd.mo +0 -0
  349. wx/locale/id/LC_MESSAGES/wxstd.mo +0 -0
  350. wx/locale/it/LC_MESSAGES/wxstd.mo +0 -0
  351. wx/locale/ja/LC_MESSAGES/wxstd.mo +0 -0
  352. wx/locale/ka/LC_MESSAGES/wxstd.mo +0 -0
  353. wx/locale/ko_KR/LC_MESSAGES/wxstd.mo +0 -0
  354. wx/locale/lt/LC_MESSAGES/wxstd.mo +0 -0
  355. wx/locale/lv/LC_MESSAGES/wxstd.mo +0 -0
  356. wx/locale/ms/LC_MESSAGES/wxstd.mo +0 -0
  357. wx/locale/nb/LC_MESSAGES/wxstd.mo +0 -0
  358. wx/locale/ne/LC_MESSAGES/wxstd.mo +0 -0
  359. wx/locale/nl/LC_MESSAGES/wxstd.mo +0 -0
  360. wx/locale/pl/LC_MESSAGES/wxstd.mo +0 -0
  361. wx/locale/pt/LC_MESSAGES/wxstd.mo +0 -0
  362. wx/locale/pt_BR/LC_MESSAGES/wxstd.mo +0 -0
  363. wx/locale/ro/LC_MESSAGES/wxstd.mo +0 -0
  364. wx/locale/ru/LC_MESSAGES/wxstd.mo +0 -0
  365. wx/locale/sk/LC_MESSAGES/wxstd.mo +0 -0
  366. wx/locale/sl/LC_MESSAGES/wxstd.mo +0 -0
  367. wx/locale/sq/LC_MESSAGES/wxstd.mo +0 -0
  368. wx/locale/sr/LC_MESSAGES/wxstd.mo +0 -0
  369. wx/locale/sv/LC_MESSAGES/wxstd.mo +0 -0
  370. wx/locale/ta/LC_MESSAGES/wxstd.mo +0 -0
  371. wx/locale/tr/LC_MESSAGES/wxstd.mo +0 -0
  372. wx/locale/uk/LC_MESSAGES/wxstd.mo +0 -0
  373. wx/locale/vi/LC_MESSAGES/wxstd.mo +0 -0
  374. wx/locale/zh_CN/LC_MESSAGES/wxstd.mo +0 -0
  375. wx/locale/zh_TW/LC_MESSAGES/wxstd.mo +0 -0
  376. wx/media.py +30 -0
  377. wx/media.pyi +272 -0
  378. wx/msw.py +16 -0
  379. wx/msw.pyi +91 -0
  380. wx/propgrid.py +498 -0
  381. wx/propgrid.pyi +7427 -0
  382. wx/py/CHANGES.txt +796 -0
  383. wx/py/Py.ico +0 -0
  384. wx/py/PyAlaCarte.py +34 -0
  385. wx/py/PyAlaMode.py +34 -0
  386. wx/py/PyAlaModeTest.py +33 -0
  387. wx/py/PyCrust.ico +0 -0
  388. wx/py/PyCrust.py +78 -0
  389. wx/py/PyCrust_16.png +0 -0
  390. wx/py/PyCrust_32.png +0 -0
  391. wx/py/PyFilling.py +35 -0
  392. wx/py/PyShell.py +78 -0
  393. wx/py/PySlices.ico +0 -0
  394. wx/py/PySlices.py +98 -0
  395. wx/py/PySlicesShell.py +94 -0
  396. wx/py/PySlices_16.png +0 -0
  397. wx/py/PySlices_32.png +0 -0
  398. wx/py/PyWrap.py +52 -0
  399. wx/py/README.txt +77 -0
  400. wx/py/__init__.py +20 -0
  401. wx/py/buffer.py +136 -0
  402. wx/py/crust.py +403 -0
  403. wx/py/crustslices.py +403 -0
  404. wx/py/dispatcher.py +259 -0
  405. wx/py/document.py +37 -0
  406. wx/py/editor.py +844 -0
  407. wx/py/editwindow.py +316 -0
  408. wx/py/filling.py +358 -0
  409. wx/py/frame.py +976 -0
  410. wx/py/images.py +212 -0
  411. wx/py/interpreter.py +161 -0
  412. wx/py/introspect.py +402 -0
  413. wx/py/magic.py +98 -0
  414. wx/py/parse.py +134 -0
  415. wx/py/path.py +36 -0
  416. wx/py/pseudo.py +99 -0
  417. wx/py/shell.py +1579 -0
  418. wx/py/sliceshell.py +3805 -0
  419. wx/py/tests/test_interpreter.py +71 -0
  420. wx/py/tests/test_introspect.py +810 -0
  421. wx/py/tests/test_pseudo.py +70 -0
  422. wx/py/tests/test_version.py +36 -0
  423. wx/py/tests/testall.py +22 -0
  424. wx/py/version.py +7 -0
  425. wx/py.typed +0 -0
  426. wx/ribbon.py +48 -0
  427. wx/ribbon.pyi +3099 -0
  428. wx/richtext.py +141 -0
  429. wx/richtext.pyi +13581 -0
  430. wx/siplib.cp315-win_amd64.pyd +0 -0
  431. wx/siplib.pyi +19 -0
  432. wx/stc.py +59 -0
  433. wx/stc.pyi +9918 -0
  434. wx/svg/__init__.py +363 -0
  435. wx/svg/_nanosvg.cp315-win_amd64.pyd +0 -0
  436. wx/tools/__init__.py +18 -0
  437. wx/tools/dbg.py +268 -0
  438. wx/tools/genaxmodule.py +50 -0
  439. wx/tools/helpviewer.py +92 -0
  440. wx/tools/img2img.py +85 -0
  441. wx/tools/img2png.py +54 -0
  442. wx/tools/img2py.py +306 -0
  443. wx/tools/img2xpm.py +54 -0
  444. wx/tools/pywxrc.py +951 -0
  445. wx/tools/wxget.py +254 -0
  446. wx/tools/wxget_docs_demo.py +183 -0
  447. wx/wxbase334u_net_vc140_x64.dll +0 -0
  448. wx/wxbase334u_vc140_x64.dll +0 -0
  449. wx/wxbase334u_xml_vc140_x64.dll +0 -0
  450. wx/wxmsw334u_adv_vc140_x64.dll +0 -0
  451. wx/wxmsw334u_aui_vc140_x64.dll +0 -0
  452. wx/wxmsw334u_core_vc140_x64.dll +0 -0
  453. wx/wxmsw334u_gl_vc140_x64.dll +0 -0
  454. wx/wxmsw334u_html_vc140_x64.dll +0 -0
  455. wx/wxmsw334u_media_vc140_x64.dll +0 -0
  456. wx/wxmsw334u_propgrid_vc140_x64.dll +0 -0
  457. wx/wxmsw334u_qa_vc140_x64.dll +0 -0
  458. wx/wxmsw334u_ribbon_vc140_x64.dll +0 -0
  459. wx/wxmsw334u_richtext_vc140_x64.dll +0 -0
  460. wx/wxmsw334u_stc_vc140_x64.dll +0 -0
  461. wx/wxmsw334u_webview_vc140_x64.dll +0 -0
  462. wx/wxmsw334u_xrc_vc140_x64.dll +0 -0
  463. wx/xml.py +18 -0
  464. wx/xml.pyi +728 -0
  465. wx/xrc.py +68 -0
  466. wx/xrc.pyi +896 -0
  467. wxpython-4.3.2.dist-info/METADATA +71 -0
  468. wxpython-4.3.2.dist-info/RECORD +472 -0
  469. wxpython-4.3.2.dist-info/WHEEL +5 -0
  470. wxpython-4.3.2.dist-info/entry_points.txt +13 -0
  471. wxpython-4.3.2.dist-info/licenses/LICENSE.txt +610 -0
  472. wxpython-4.3.2.dist-info/top_level.txt +1 -0
wx/lib/ogl/composit.py ADDED
@@ -0,0 +1,1576 @@
1
+ # -*- coding: utf-8 -*-
2
+ #----------------------------------------------------------------------------
3
+ # Name: composit.py
4
+ # Purpose: Composite class
5
+ #
6
+ # Author: Pierre Hjälm (from C++ original by Julian Smart)
7
+ #
8
+ # Created: 2004-05-08
9
+ # Copyright: (c) 2004 Pierre Hjälm - 1998 Julian Smart
10
+ # Licence: wxWindows license
11
+ # Tags: phoenix-port, unittest, py3-port, documented
12
+ #----------------------------------------------------------------------------
13
+ """
14
+ The :class:`~lib.ogl.composit.CompositeShape` class.
15
+ """
16
+ import sys
17
+ import wx
18
+
19
+ from .basic import RectangleShape, Shape, ControlPoint
20
+ from .oglmisc import *
21
+
22
+ _objectStartX = 0.0
23
+ _objectStartY = 0.0
24
+
25
+ CONSTRAINT_CENTRED_VERTICALLY = 1
26
+ CONSTRAINT_CENTRED_HORIZONTALLY = 2
27
+ CONSTRAINT_CENTRED_BOTH = 3
28
+ CONSTRAINT_LEFT_OF = 4
29
+ CONSTRAINT_RIGHT_OF = 5
30
+ CONSTRAINT_ABOVE = 6
31
+ CONSTRAINT_BELOW = 7
32
+ CONSTRAINT_ALIGNED_TOP = 8
33
+ CONSTRAINT_ALIGNED_BOTTOM = 9
34
+ CONSTRAINT_ALIGNED_LEFT = 10
35
+ CONSTRAINT_ALIGNED_RIGHT = 11
36
+
37
+ # Like aligned, but with the objects centred on the respective edge
38
+ # of the reference object.
39
+ CONSTRAINT_MIDALIGNED_TOP = 12
40
+ CONSTRAINT_MIDALIGNED_BOTTOM = 13
41
+ CONSTRAINT_MIDALIGNED_LEFT = 14
42
+ CONSTRAINT_MIDALIGNED_RIGHT = 15
43
+
44
+
45
+ class ConstraintType(object):
46
+ """The :class:`ConstraintType` class."""
47
+ def __init__(self, theType, theName, thePhrase):
48
+ """
49
+ Default class constructor.
50
+
51
+ :param `theType`: one of the following
52
+ ====================================== ================================
53
+ Constraint type Description
54
+ ====================================== ================================
55
+ `CONSTRAINT_CENTRED_VERTICALLY` Centered vertically
56
+ `CONSTRAINT_CENTRED_HORIZONTALLY` Centered horizontally
57
+ `CONSTRAINT_CENTRED_BOTH` Centered in both directions
58
+ `CONSTRAINT_LEFT_OF` Center left of
59
+ `CONSTRAINT_RIGHT_OF` Center right of
60
+ `CONSTRAINT_ABOVE` Center above
61
+ `CONSTRAINT_BELOW` Center below
62
+ `CONSTRAINT_ALIGNED_TOP` Align top
63
+ `CONSTRAINT_ALIGNED_BOTTOM` Align bottom
64
+ `CONSTRAINT_ALIGNED_LEFT` Align left
65
+ `CONSTRAINT_ALIGNED_RIGHT` Align right
66
+ `CONSTRAINT_MIDALIGNED_TOP` Middle align top
67
+ `CONSTRAINT_MIDALIGNED_BOTTOM` Middle align bottom
68
+ `CONSTRAINT_MIDALIGNED_LEFT` Middle align left
69
+ `CONSTRAINT_MIDALIGNED_RIGHT` Middle align right
70
+ ====================================== ================================
71
+
72
+ :param `theName`: the name for the constraint
73
+ :param `thePhrase`: the descriptive phrase
74
+
75
+ """
76
+ self._type = theType
77
+ self._name = theName
78
+ self._phrase = thePhrase
79
+
80
+
81
+
82
+ ConstraintTypes = [
83
+ [CONSTRAINT_CENTRED_VERTICALLY,
84
+ ConstraintType(CONSTRAINT_CENTRED_VERTICALLY, "Centre vertically", "centred vertically w.r.t.")],
85
+
86
+ [CONSTRAINT_CENTRED_HORIZONTALLY,
87
+ ConstraintType(CONSTRAINT_CENTRED_HORIZONTALLY, "Centre horizontally", "centred horizontally w.r.t.")],
88
+
89
+ [CONSTRAINT_CENTRED_BOTH,
90
+ ConstraintType(CONSTRAINT_CENTRED_BOTH, "Centre", "centred w.r.t.")],
91
+
92
+ [CONSTRAINT_LEFT_OF,
93
+ ConstraintType(CONSTRAINT_LEFT_OF, "Left of", "left of")],
94
+
95
+ [CONSTRAINT_RIGHT_OF,
96
+ ConstraintType(CONSTRAINT_RIGHT_OF, "Right of", "right of")],
97
+
98
+ [CONSTRAINT_ABOVE,
99
+ ConstraintType(CONSTRAINT_ABOVE, "Above", "above")],
100
+
101
+ [CONSTRAINT_BELOW,
102
+ ConstraintType(CONSTRAINT_BELOW, "Below", "below")],
103
+
104
+ # Alignment
105
+ [CONSTRAINT_ALIGNED_TOP,
106
+ ConstraintType(CONSTRAINT_ALIGNED_TOP, "Top-aligned", "aligned to the top of")],
107
+
108
+ [CONSTRAINT_ALIGNED_BOTTOM,
109
+ ConstraintType(CONSTRAINT_ALIGNED_BOTTOM, "Bottom-aligned", "aligned to the bottom of")],
110
+
111
+ [CONSTRAINT_ALIGNED_LEFT,
112
+ ConstraintType(CONSTRAINT_ALIGNED_LEFT, "Left-aligned", "aligned to the left of")],
113
+
114
+ [CONSTRAINT_ALIGNED_RIGHT,
115
+ ConstraintType(CONSTRAINT_ALIGNED_RIGHT, "Right-aligned", "aligned to the right of")],
116
+
117
+ # Mid-alignment
118
+ [CONSTRAINT_MIDALIGNED_TOP,
119
+ ConstraintType(CONSTRAINT_MIDALIGNED_TOP, "Top-midaligned", "centred on the top of")],
120
+
121
+ [CONSTRAINT_MIDALIGNED_BOTTOM,
122
+ ConstraintType(CONSTRAINT_MIDALIGNED_BOTTOM, "Bottom-midaligned", "centred on the bottom of")],
123
+
124
+ [CONSTRAINT_MIDALIGNED_LEFT,
125
+ ConstraintType(CONSTRAINT_MIDALIGNED_LEFT, "Left-midaligned", "centred on the left of")],
126
+
127
+ [CONSTRAINT_MIDALIGNED_RIGHT,
128
+ ConstraintType(CONSTRAINT_MIDALIGNED_RIGHT, "Right-midaligned", "centred on the right of")]
129
+ ]
130
+
131
+
132
+ class Constraint(object):
133
+ """
134
+ The :class:`Constraint` class helps specify how child shapes are laid out
135
+ with respect to siblings and parents.
136
+ """
137
+ def __init__(self, type, constraining, constrained):
138
+ """
139
+ Default class constructor.
140
+
141
+ :param `type`: see :class:`ConstraintType` for valid types
142
+ :param `constraining`: the constraining :class:`Shape`
143
+ :param `constrained`: the constrained :class:`Shape`
144
+
145
+ """
146
+ self._xSpacing = 0.0
147
+ self._ySpacing = 0.0
148
+
149
+ self._constraintType = type
150
+ self._constrainingObject = constraining
151
+
152
+ self._constraintId = 0
153
+ self._constraintName = "noname"
154
+
155
+ self._constrainedObjects = constrained[:]
156
+
157
+ def __repr__(self):
158
+ return "<%s.%s>" % (self.__class__.__module__, self.__class__.__name__)
159
+
160
+ def SetSpacing(self, x, y):
161
+ """
162
+ Sets the horizontal and vertical spacing for the constraint.
163
+
164
+ :param `x`: the x position
165
+ :param `y`: the y position
166
+
167
+ """
168
+ self._xSpacing = x
169
+ self._ySpacing = y
170
+
171
+ def Equals(self, a, b):
172
+ """
173
+ Return `True` if a and b are approximately equal (for the purposes
174
+ of evaluating the constraint).
175
+
176
+ :param `a`: ???
177
+ :param `b`: ???
178
+
179
+ """
180
+ marg = 0.5
181
+
182
+ return b <= a + marg and b >= a - marg
183
+
184
+ def Evaluate(self):
185
+ """Evaluate this constraint and return `True` if anything changed."""
186
+ maxWidth, maxHeight = self._constrainingObject.GetBoundingBoxMax()
187
+ minWidth, minHeight = self._constrainingObject.GetBoundingBoxMin()
188
+ x = self._constrainingObject.GetX()
189
+ y = self._constrainingObject.GetY()
190
+
191
+ dc = wx.MemoryDC()
192
+ dc.SelectObject(self._constrainingObject.GetCanvas().GetBuffer())
193
+ self._constrainingObject.GetCanvas().PrepareDC(dc)
194
+
195
+ if self._constraintType == CONSTRAINT_CENTRED_VERTICALLY:
196
+ n = len(self._constrainedObjects)
197
+ totalObjectHeight = 0.0
198
+ for constrainedObject in self._constrainedObjects:
199
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
200
+ totalObjectHeight += height2
201
+
202
+ # Check if within the constraining object...
203
+ if totalObjectHeight + (n + 1) * self._ySpacing <= minHeight:
204
+ spacingY = (minHeight - totalObjectHeight) / (n + 1.0)
205
+ startY = y - minHeight / 2.0
206
+ else: # Otherwise, use default spacing
207
+ spacingY = self._ySpacing
208
+ startY = y - (totalObjectHeight + (n + 1) * spacingY) / 2.0
209
+
210
+ # Now position the objects
211
+ changed = False
212
+ for constrainedObject in self._constrainedObjects:
213
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
214
+ startY += spacingY + height2 / 2.0
215
+ if not self.Equals(startY, constrainedObject.GetY()):
216
+ constrainedObject.Move(dc, constrainedObject.GetX(), startY, False)
217
+ changed = True
218
+ startY += height2 / 2.0
219
+ return changed
220
+ elif self._constraintType == CONSTRAINT_CENTRED_HORIZONTALLY:
221
+ n = len(self._constrainedObjects)
222
+ totalObjectWidth = 0.0
223
+ for constrainedObject in self._constrainedObjects:
224
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
225
+ totalObjectWidth += width2
226
+
227
+ # Check if within the constraining object...
228
+ if totalObjectWidth + (n + 1) * self._xSpacing <= minWidth:
229
+ spacingX = (minWidth - totalObjectWidth) / (n + 1.0)
230
+ startX = x - minWidth / 2.0
231
+ else: # Otherwise, use default spacing
232
+ spacingX = self._xSpacing
233
+ startX = x - (totalObjectWidth + (n + 1) * spacingX) / 2.0
234
+
235
+ # Now position the objects
236
+ changed = False
237
+ for constrainedObject in self._constrainedObjects:
238
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
239
+ startX += spacingX + width2 / 2.0
240
+ if not self.Equals(startX, constrainedObject.GetX()):
241
+ constrainedObject.Move(dc, startX, constrainedObject.GetY(), False)
242
+ changed = True
243
+ startX += width2 / 2.0
244
+ return changed
245
+ elif self._constraintType == CONSTRAINT_CENTRED_BOTH:
246
+ n = len(self._constrainedObjects)
247
+ totalObjectWidth = 0.0
248
+ totalObjectHeight = 0.0
249
+
250
+ for constrainedObject in self._constrainedObjects:
251
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
252
+ totalObjectWidth += width2
253
+ totalObjectHeight += height2
254
+
255
+ # Check if within the constraining object...
256
+ if totalObjectHeight + (n + 1) * self._xSpacing <= minWidth:
257
+ spacingX = (minWidth - totalObjectWidth) / (n + 1.0)
258
+ startX = x - minWidth / 2.0
259
+ else: # Otherwise, use default spacing
260
+ spacingX = self._xSpacing
261
+ startX = x - (totalObjectWidth + (n + 1) * spacingX) / 2.0
262
+
263
+ # Check if within the constraining object...
264
+ if totalObjectHeight + (n + 1) * self._ySpacing <= minHeight:
265
+ spacingY = (minHeight - totalObjectHeight) / (n + 1.0)
266
+ startY = y - minHeight / 2.0
267
+ else: # Otherwise, use default spacing
268
+ spacingY = self._ySpacing
269
+ startY = y - (totalObjectHeight + (n + 1) * spacingY) / 2.0
270
+
271
+ # Now position the objects
272
+ changed = False
273
+ for constrainedObject in self._constrainedObjects:
274
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
275
+ startX += spacingX + width2 / 2.0
276
+ startY += spacingY + height2 / 2.0
277
+
278
+ if not self.Equals(startX, constrainedObject.GetX()) or not self.Equals(startY, constrainedObject.GetY()):
279
+ constrainedObject.Move(dc, startX, startY, False)
280
+ changed = True
281
+
282
+ startX += width2 / 2.0
283
+ startY += height2 / 2.0
284
+ return changed
285
+ elif self._constraintType == CONSTRAINT_LEFT_OF:
286
+ changed = False
287
+ for constrainedObject in self._constrainedObjects:
288
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
289
+
290
+ x3 = x - minWidth / 2.0 - width2 / 2.0 - self._xSpacing
291
+ if not self.Equals(x3, constrainedObject.GetX()):
292
+ changed = True
293
+ constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
294
+ return changed
295
+ elif self._constraintType == CONSTRAINT_RIGHT_OF:
296
+ changed = False
297
+
298
+ for constrainedObject in self._constrainedObjects:
299
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
300
+ x3 = x + minWidth / 2.0 + width2 / 2.0 + self._xSpacing
301
+ if not self.Equals(x3, constrainedObject.GetX()):
302
+ constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
303
+ changed = True
304
+ return changed
305
+ elif self._constraintType == CONSTRAINT_ABOVE:
306
+ changed = False
307
+
308
+ for constrainedObject in self._constrainedObjects:
309
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
310
+
311
+ y3 = y - minHeight / 2.0 - height2 / 2.0 - self._ySpacing
312
+ if not self.Equals(y3, constrainedObject.GetY()):
313
+ changed = True
314
+ constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
315
+ return changed
316
+ elif self._constraintType == CONSTRAINT_BELOW:
317
+ changed = False
318
+
319
+ for constrainedObject in self._constrainedObjects:
320
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
321
+
322
+ y3 = y + minHeight / 2.0 + height2 / 2.0 + self._ySpacing
323
+ if not self.Equals(y3, constrainedObject.GetY()):
324
+ changed = True
325
+ constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
326
+ return changed
327
+ elif self._constraintType == CONSTRAINT_ALIGNED_LEFT:
328
+ changed = False
329
+ for constrainedObject in self._constrainedObjects:
330
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
331
+ x3 = x - minWidth / 2.0 + width2 / 2.0 + self._xSpacing
332
+ if not self.Equals(x3, constrainedObject.GetX()):
333
+ changed = True
334
+ constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
335
+ return changed
336
+ elif self._constraintType == CONSTRAINT_ALIGNED_RIGHT:
337
+ changed = False
338
+ for constrainedObject in self._constrainedObjects:
339
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
340
+ x3 = x + minWidth / 2.0 - width2 / 2.0 - self._xSpacing
341
+ if not self.Equals(x3, constrainedObject.GetX()):
342
+ changed = True
343
+ constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
344
+ return changed
345
+ elif self._constraintType == CONSTRAINT_ALIGNED_TOP:
346
+ changed = False
347
+ for constrainedObject in self._constrainedObjects:
348
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
349
+ y3 = y - minHeight / 2.0 + height2 / 2.0 + self._ySpacing
350
+ if not self.Equals(y3, constrainedObject.GetY()):
351
+ changed = True
352
+ constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
353
+ return changed
354
+ elif self._constraintType == CONSTRAINT_ALIGNED_BOTTOM:
355
+ changed = False
356
+ for constrainedObject in self._constrainedObjects:
357
+ width2, height2 = constrainedObject.GetBoundingBoxMax()
358
+ y3 = y + minHeight / 2.0 - height2 / 2.0 - self._ySpacing
359
+ if not self.Equals(y3, constrainedObject.GetY()):
360
+ changed = True
361
+ constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
362
+ return changed
363
+ elif self._constraintType == CONSTRAINT_MIDALIGNED_LEFT:
364
+ changed = False
365
+ for constrainedObject in self._constrainedObjects:
366
+ x3 = x - minWidth / 2.0
367
+ if not self.Equals(x3, constrainedObject.GetX()):
368
+ changed = True
369
+ constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
370
+ return changed
371
+ elif self._constraintType == CONSTRAINT_MIDALIGNED_RIGHT:
372
+ changed = False
373
+ for constrainedObject in self._constrainedObjects:
374
+ x3 = x + minWidth / 2.0
375
+ if not self.Equals(x3, constrainedObject.GetX()):
376
+ changed = True
377
+ constrainedObject.Move(dc, x3, constrainedObject.GetY(), False)
378
+ return changed
379
+ elif self._constraintType == CONSTRAINT_MIDALIGNED_TOP:
380
+ changed = False
381
+ for constrainedObject in self._constrainedObjects:
382
+ y3 = y - minHeight / 2.0
383
+ if not self.Equals(y3, constrainedObject.GetY()):
384
+ changed = True
385
+ constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
386
+ return changed
387
+ elif self._constraintType == CONSTRAINT_MIDALIGNED_BOTTOM:
388
+ changed = False
389
+ for constrainedObject in self._constrainedObjects:
390
+ y3 = y + minHeight / 2.0
391
+ if not self.Equals(y3, constrainedObject.GetY()):
392
+ changed = True
393
+ constrainedObject.Move(dc, constrainedObject.GetX(), y3, False)
394
+ return changed
395
+
396
+ return False
397
+
398
+ OGLConstraint = wx.deprecated(Constraint,
399
+ "The OGLConstraint name is deprecated, use `ogl.Constraint` instead.")
400
+
401
+
402
+ class CompositeShape(RectangleShape):
403
+ """
404
+ The :class:`CompositeShape` is a shape with a list of child objects, and a
405
+ list of size and positioning constraints between the children.
406
+ """
407
+ def __init__(self):
408
+ """
409
+ Default class constructor.
410
+
411
+ """
412
+ RectangleShape.__init__(self, 100.0, 100.0)
413
+
414
+ self._oldX = self._xpos
415
+ self._oldY = self._ypos
416
+
417
+ self._constraints = []
418
+ self._divisions = [] # In case it's a container
419
+
420
+ def OnDraw(self, dc):
421
+ """The draw handler."""
422
+ x1 = self._xpos - self._width / 2.0
423
+ y1 = self._ypos - self._height / 2.0
424
+
425
+ if self._shadowMode != SHADOW_NONE:
426
+ if self._shadowBrush:
427
+ dc.SetBrush(self._shadowBrush)
428
+ dc.SetPen(wx.Pen(wx.WHITE, 1, wx.PENSTYLE_TRANSPARENT))
429
+
430
+ if self._cornerRadius:
431
+ dc.DrawRoundedRectangle(x1 + self._shadowOffsetX, y1 + self._shadowOffsetY, self._width, self._height, self._cornerRadius)
432
+ else:
433
+ dc.DrawRectangle(x1 + self._shadowOffsetX, y1 + self._shadowOffsetY, self._width, self._height)
434
+
435
+ # For debug purposes /pi
436
+ #dc.DrawRectangle(x1, y1, self._width, self._height)
437
+
438
+ def OnDrawContents(self, dc):
439
+ """The draw contents handler."""
440
+ for object in self._children:
441
+ object.Draw(dc)
442
+ object.DrawLinks(dc)
443
+
444
+ Shape.OnDrawContents(self, dc)
445
+
446
+ def OnMovePre(self, dc, x, y, old_x, old_y, display = True):
447
+ """The move 'pre' handler."""
448
+ diffX = x - old_x
449
+ diffY = y - old_y
450
+
451
+ for object in self._children:
452
+ object.Erase(dc)
453
+ object.Move(dc, object.GetX() + diffX, object.GetY() + diffY, display)
454
+
455
+ return True
456
+
457
+ def OnErase(self, dc):
458
+ """The erase handler."""
459
+ RectangleShape.OnErase(self, dc)
460
+ for object in self._children:
461
+ object.Erase(dc)
462
+
463
+ def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
464
+ """The drag left handler."""
465
+ xx, yy = self._canvas.Snap(x, y)
466
+ offsetX = xx - _objectStartX
467
+ offsetY = yy - _objectStartY
468
+
469
+ dc = wx.ClientDC(self.GetCanvas())
470
+ self.GetCanvas().PrepareDC(dc)
471
+ dc.SetLogicalFunction(OGLRBLF)
472
+
473
+ dottedPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)
474
+ dc.SetPen(dottedPen)
475
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
476
+
477
+ self.GetEventHandler().OnDrawOutline(dc, self.GetX() + offsetX, self.GetY() + offsetY, self.GetWidth(), self.GetHeight())
478
+
479
+ def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
480
+ """The begin drag left handler."""
481
+ global _objectStartX, _objectStartY
482
+
483
+ _objectStartX = x
484
+ _objectStartY = y
485
+
486
+ dc = wx.ClientDC(self.GetCanvas())
487
+ self.GetCanvas().PrepareDC(dc)
488
+ dc.SetLogicalFunction(OGLRBLF)
489
+
490
+ dottedPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)
491
+ dc.SetPen(dottedPen)
492
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
493
+ self._canvas.CaptureMouse()
494
+
495
+ xx, yy = self._canvas.Snap(x, y)
496
+ offsetX = xx - _objectStartX
497
+ offsetY = yy - _objectStartY
498
+
499
+ self.GetEventHandler().OnDrawOutline(dc, self.GetX() + offsetX, self.GetY() + offsetY, self.GetWidth(), self.GetHeight())
500
+
501
+ def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
502
+ """The end drag left handler."""
503
+ if self._canvas.HasCapture():
504
+ self._canvas.ReleaseMouse()
505
+
506
+ if not self._draggable:
507
+ if self._parent:
508
+ self._parent.GetEventHandler().OnEndDragLeft(x, y, keys, 0)
509
+ return
510
+
511
+ dc = wx.ClientDC(self.GetCanvas())
512
+ self.GetCanvas().PrepareDC(dc)
513
+ dc.SetLogicalFunction(wx.COPY)
514
+
515
+ self.Erase(dc)
516
+
517
+ xx, yy = self._canvas.Snap(x, y)
518
+ offsetX = xx - _objectStartX
519
+ offsetY = yy - _objectStartY
520
+
521
+ self.Move(dc, self.GetX() + offsetX, self.GetY() + offsetY)
522
+
523
+ if self._canvas and not self._canvas.GetQuickEditMode():
524
+ self._canvas.Redraw(dc)
525
+
526
+ def OnRightClick(self, x, y, keys = 0, attachment = 0):
527
+ """The right click handler.
528
+
529
+ :note: If we get a ctrl-right click, this means send the message to
530
+ the division, so we can invoke a user interface for dealing
531
+ with regions.
532
+ """
533
+ if keys & KEY_CTRL:
534
+ for division in self._divisions:
535
+ hit = division.HitTest(x, y)
536
+ if hit:
537
+ division.GetEventHandler().OnRightClick(x, y, keys, hit[0])
538
+ break
539
+
540
+ def SetSize(self, w, h, recursive = True):
541
+ """
542
+ Set the size.
543
+
544
+ :param `w`: the width
545
+ :param `h`: the height
546
+ :param `recursive`: size the children recursively
547
+
548
+ """
549
+ self.SetAttachmentSize(w, h)
550
+
551
+ xScale = float(w) / max(1, self.GetWidth())
552
+ yScale = float(h) / max(1, self.GetHeight())
553
+
554
+ self._width = w
555
+ self._height = h
556
+
557
+ if not recursive:
558
+ return
559
+
560
+ dc = wx.MemoryDC()
561
+ dc.SelectObject(self.GetCanvas().GetBuffer())
562
+ self.GetCanvas().PrepareDC(dc)
563
+
564
+ for object in self._children:
565
+ # Scale the position first
566
+ newX = (object.GetX() - self.GetX()) * xScale + self.GetX()
567
+ newY = (object.GetY() - self.GetY()) * yScale + self.GetY()
568
+ object.Show(False)
569
+ object.Move(dc, newX, newY)
570
+ object.Show(True)
571
+
572
+ # Now set the scaled size
573
+ xbound, ybound = object.GetBoundingBoxMax()
574
+ if not object.GetFixedWidth():
575
+ xbound *= xScale
576
+ if not object.GetFixedHeight():
577
+ ybound *= yScale
578
+ object.SetSize(xbound, ybound)
579
+
580
+ self.SetDefaultRegionSize()
581
+
582
+ def AddChild(self, child, addAfter = None):
583
+ """
584
+ Add a shape to the composite. If addAfter is not None, the shape
585
+ will be added after addAfter.
586
+
587
+ :param `child`: an instance of :class:`~lib.ogl.Shape`
588
+ :param `addAfter`: an instance of :class:`~lib.ogl.Shape`
589
+
590
+ """
591
+ self._children.append(child)
592
+ child.SetParent(self)
593
+ if self._canvas:
594
+ # Ensure we add at the right position
595
+ if addAfter:
596
+ child.RemoveFromCanvas(self._canvas)
597
+ child.AddToCanvas(self._canvas, addAfter)
598
+
599
+ def RemoveChild(self, child):
600
+ """
601
+ Removes the child from the composite and any constraint
602
+ relationships, but does not delete the child.
603
+
604
+ :param `child`: an instance of :class:`~lib.ogl.Shape`
605
+
606
+ """
607
+ if child in self._children:
608
+ self._children.remove(child)
609
+ if child in self._divisions:
610
+ self._divisions.remove(child)
611
+ self.RemoveChildFromConstraints(child)
612
+ child.SetParent(None)
613
+
614
+ def Delete(self):
615
+ """
616
+ Fully disconnect this shape from parents, children, the
617
+ canvas, etc.
618
+ """
619
+ for child in self.GetChildren():
620
+ self.RemoveChild(child)
621
+ child.Delete()
622
+ RectangleShape.Delete(self)
623
+ self._constraints = []
624
+ self._divisions = []
625
+
626
+ def DeleteConstraintsInvolvingChild(self, child):
627
+ """
628
+ This function deletes constraints which mention the given child.
629
+
630
+ Used when deleting a child from the composite.
631
+
632
+ :param `child`: an instance of :class:`~lib.ogl.Shape`
633
+
634
+ """
635
+ for constraint in self._constraints:
636
+ if constraint._constrainingObject == child or child in constraint._constrainedObjects:
637
+ self._constraints.remove(constraint)
638
+
639
+ def RemoveChildFromConstraints(self, child):
640
+ """
641
+ Removes the child from the constraints.
642
+
643
+ :param `child`: an instance of :class:`~lib.ogl.Shape`
644
+
645
+ """
646
+
647
+ for constraint in self._constraints:
648
+ if child in constraint._constrainedObjects:
649
+ constraint._constrainedObjects.remove(child)
650
+ if constraint._constrainingObject == child:
651
+ constraint._constrainingObject = None
652
+
653
+ # Delete the constraint if no participants left
654
+ if not constraint._constrainingObject:
655
+ self._constraints.remove(constraint)
656
+
657
+ def AddConstraint(self, constraint):
658
+ """
659
+ Adds a constraint to the composite.
660
+
661
+ :param `constraint`: an instance of :class:`~lib.ogl.Shape`
662
+
663
+ """
664
+ self._constraints.append(constraint)
665
+ if constraint._constraintId == 0:
666
+ constraint._constraintId = wx.NewIdRef()
667
+ return constraint
668
+
669
+ def AddSimpleConstraint(self, type, constraining, constrained):
670
+ """
671
+ Add a constraint of the given type to the composite.
672
+
673
+ :param `type`: see :class:`ConstraintType` for valid types
674
+ :param `constraining`: the constraining :class:`Shape`
675
+ :param `constrained`: the constrained :class:`Shape`
676
+
677
+ """
678
+ constraint = Constraint(type, constraining, constrained)
679
+ if constraint._constraintId == 0:
680
+ constraint._constraintId = wx.NewIdRef()
681
+ self._constraints.append(constraint)
682
+ return constraint
683
+
684
+ def FindConstraint(self, cId):
685
+ """
686
+ Finds the constraint with the given id.
687
+
688
+ :param `cId`: The constraint id to find.
689
+
690
+ :returns: None or a tuple of the constraint and the actual composite the
691
+ constraint was in, in case that composite was a descendant of
692
+ this composit.
693
+
694
+ """
695
+ for constraint in self._constraints:
696
+ if constraint._constraintId == cId:
697
+ return constraint, self
698
+
699
+ # If not found, try children
700
+ for child in self._children:
701
+ if isinstance(child, CompositeShape):
702
+ constraint = child.FindConstraint(cId)
703
+ if constraint:
704
+ return constraint[0], child
705
+
706
+ return None
707
+
708
+ def DeleteConstraint(self, constraint):
709
+ """
710
+ Deletes constraint from composite.
711
+
712
+ :param `constraint`: the constraint to delete
713
+
714
+ """
715
+ self._constraints.remove(constraint)
716
+
717
+ def CalculateSize(self):
718
+ """
719
+ Calculates the size and position of the composite based on
720
+ child sizes and positions.
721
+
722
+ """
723
+ maxX = -999999.9
724
+ maxY = -999999.9
725
+ minX = 999999.9
726
+ minY = 999999.9
727
+
728
+ for child in self._children:
729
+ # Recalculate size of composite objects because may not conform
730
+ # to size it was set to - depends on the children.
731
+ if isinstance(child, CompositeShape):
732
+ child.CalculateSize()
733
+
734
+ w, h = child.GetBoundingBoxMax()
735
+ if child.GetX() + w / 2.0 > maxX:
736
+ maxX = child.GetX() + w / 2.0
737
+ if child.GetX() - w / 2.0 < minX:
738
+ minX = child.GetX() - w / 2.0
739
+ if child.GetY() + h / 2.0 > maxY:
740
+ maxY = child.GetY() + h / 2.0
741
+ if child.GetY() - h / 2.0 < minY:
742
+ minY = child.GetY() - h / 2.0
743
+
744
+ self._width = maxX - minX
745
+ self._height = maxY - minY
746
+ self._xpos = self._width / 2.0 + minX
747
+ self._ypos = self._height / 2.0 + minY
748
+
749
+ def Recompute(self):
750
+ """
751
+ Recomputes any constraints associated with the object. If `False` is
752
+ returned, the constraints could not be satisfied (there was an
753
+ inconsistency).
754
+
755
+ """
756
+ noIterations = 0
757
+ changed = True
758
+ while changed and noIterations < 500:
759
+ changed = self.Constrain()
760
+ noIterations += 1
761
+
762
+ return not changed
763
+
764
+ def Constrain(self):
765
+ """
766
+ Constrain the children.
767
+
768
+ :returns: True if constrained otherwise False
769
+
770
+ """
771
+ self.CalculateSize()
772
+
773
+ changed = False
774
+ for child in self._children:
775
+ if isinstance(child, CompositeShape) and child.Constrain():
776
+ changed = True
777
+
778
+ for constraint in self._constraints:
779
+ if constraint.Evaluate():
780
+ changed = True
781
+
782
+ return changed
783
+
784
+ def MakeContainer(self):
785
+ """
786
+ Makes this composite into a container by creating one child
787
+ DivisionShape.
788
+ """
789
+ division = self.OnCreateDivision()
790
+ self._divisions.append(division)
791
+ self.AddChild(division)
792
+
793
+ division.SetSize(self._width, self._height)
794
+
795
+ dc = wx.MemoryDC()
796
+ dc.SelectObject(self.GetCanvas().GetBuffer())
797
+ self.GetCanvas().PrepareDC(dc)
798
+
799
+ division.Move(dc, self.GetX(), self.GetY())
800
+ self.Recompute()
801
+ division.Show(True)
802
+
803
+ def OnCreateDivision(self):
804
+ """Create division handler."""
805
+ return DivisionShape()
806
+
807
+ def FindContainerImage(self):
808
+ """
809
+ Finds the image used to visualize a container. This is any child of
810
+ the composite that is not in the divisions list.
811
+
812
+ """
813
+ for child in self._children:
814
+ if child in self._divisions:
815
+ return child
816
+
817
+ return None
818
+
819
+ def ContainsDivision(self, division):
820
+ """
821
+ Check if division is descendant.
822
+
823
+ :param `division`: division to check
824
+ :returns: `True` if division is a descendant of this container.
825
+
826
+ """
827
+ if division in self._divisions:
828
+ return True
829
+
830
+ for child in self._children:
831
+ if isinstance(child, CompositeShape):
832
+ return child.ContainsDivision(division)
833
+
834
+ return False
835
+
836
+ def GetDivisions(self):
837
+ """Return the list of divisions."""
838
+ return self._divisions
839
+
840
+ def GetConstraints(self):
841
+ """Return the list of constraints."""
842
+ return self._constraints
843
+
844
+
845
+ DIVISION_SIDE_NONE =0
846
+ DIVISION_SIDE_LEFT =1
847
+ DIVISION_SIDE_TOP =2
848
+ DIVISION_SIDE_RIGHT =3
849
+ DIVISION_SIDE_BOTTOM =4
850
+
851
+ originalX = 0.0
852
+ originalY = 0.0
853
+ originalW = 0.0
854
+ originalH = 0.0
855
+
856
+
857
+
858
+ class DivisionControlPoint(ControlPoint):
859
+ def __init__(self, the_canvas, object, size, the_xoffset, the_yoffset, the_type):
860
+ ControlPoint.__init__(self, the_canvas, object, size, the_xoffset, the_yoffset, the_type)
861
+ self.SetEraseObject(False)
862
+
863
+ # Implement resizing of canvas object
864
+ def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
865
+ ControlPoint.OnDragLeft(self, draw, x, y, keys, attachment)
866
+
867
+ def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
868
+ global originalX, originalY, originalW, originalH
869
+
870
+ originalX = self._shape.GetX()
871
+ originalY = self._shape.GetY()
872
+ originalW = self._shape.GetWidth()
873
+ originalH = self._shape.GetHeight()
874
+
875
+ ControlPoint.OnBeginDragLeft(self, x, y, keys, attachment)
876
+
877
+ def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
878
+ ControlPoint.OnEndDragLeft(self, x, y, keys, attachment)
879
+
880
+ dc = wx.MemoryDC()
881
+ dc.SelectObject(self.GetCanvas().GetBuffer())
882
+ self.GetCanvas().PrepareDC(dc)
883
+
884
+ division = self._shape
885
+ divisionParent = division.GetParent()
886
+
887
+ # Need to check it's within the bounds of the parent composite
888
+ x1 = divisionParent.GetX() - divisionParent.GetWidth() / 2.0
889
+ y1 = divisionParent.GetY() - divisionParent.GetHeight() / 2.0
890
+ x2 = divisionParent.GetX() + divisionParent.GetWidth() / 2.0
891
+ y2 = divisionParent.GetY() + divisionParent.GetHeight() / 2.0
892
+
893
+ # Need to check it has not made the division zero or negative
894
+ # width / height
895
+ dx1 = division.GetX() - division.GetWidth() / 2.0
896
+ dy1 = division.GetY() - division.GetHeight() / 2.0
897
+ dx2 = division.GetX() + division.GetWidth() / 2.0
898
+ dy2 = division.GetY() + division.GetHeight() / 2.0
899
+
900
+ success = True
901
+ if division.GetHandleSide() == DIVISION_SIDE_LEFT:
902
+ if x <= x1 or x >= x2 or x >= dx2:
903
+ success = False
904
+ # Try it out first...
905
+ elif not division.ResizeAdjoining(DIVISION_SIDE_LEFT, x, True):
906
+ success = False
907
+ else:
908
+ division.ResizeAdjoining(DIVISION_SIDE_LEFT, x, False)
909
+ elif division.GetHandleSide() == DIVISION_SIDE_TOP:
910
+ if y <= y1 or y >= y2 or y >= dy2:
911
+ success = False
912
+ elif not division.ResizeAdjoining(DIVISION_SIDE_TOP, y, True):
913
+ success = False
914
+ else:
915
+ division.ResizingAdjoining(DIVISION_SIDE_TOP, y, False)
916
+ elif division.GetHandleSide() == DIVISION_SIDE_RIGHT:
917
+ if x <= x1 or x >= x2 or x <= dx1:
918
+ success = False
919
+ elif not division.ResizeAdjoining(DIVISION_SIDE_RIGHT, x, True):
920
+ success = False
921
+ else:
922
+ division.ResizeAdjoining(DIVISION_SIDE_RIGHT, x, False)
923
+ elif division.GetHandleSide() == DIVISION_SIDE_BOTTOM:
924
+ if y <= y1 or y >= y2 or y <= dy1:
925
+ success = False
926
+ elif not division.ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, True):
927
+ success = False
928
+ else:
929
+ division.ResizeAdjoining(DIVISION_SIDE_BOTTOM, y, False)
930
+
931
+ if not success:
932
+ division.SetSize(originalW, originalH)
933
+ division.Move(dc, originalX, originalY)
934
+
935
+ divisionParent.Draw(dc)
936
+ division.GetEventHandler().OnDrawControlPoints(dc)
937
+
938
+
939
+
940
+ DIVISION_MENU_SPLIT_HORIZONTALLY =1
941
+ DIVISION_MENU_SPLIT_VERTICALLY =2
942
+ DIVISION_MENU_EDIT_LEFT_EDGE =3
943
+ DIVISION_MENU_EDIT_TOP_EDGE =4
944
+ DIVISION_MENU_EDIT_RIGHT_EDGE =5
945
+ DIVISION_MENU_EDIT_BOTTOM_EDGE =6
946
+ DIVISION_MENU_DELETE_ALL =7
947
+
948
+
949
+
950
+ class PopupDivisionMenu(wx.Menu):
951
+ def __init__(self):
952
+ wx.Menu.__init__(self)
953
+ self.Append(DIVISION_MENU_SPLIT_HORIZONTALLY,"Split horizontally")
954
+ self.Append(DIVISION_MENU_SPLIT_VERTICALLY,"Split vertically")
955
+ self.AppendSeparator()
956
+ self.Append(DIVISION_MENU_EDIT_LEFT_EDGE,"Edit left edge")
957
+ self.Append(DIVISION_MENU_EDIT_TOP_EDGE,"Edit top edge")
958
+
959
+ wx.EVT_MENU_RANGE(self, DIVISION_MENU_SPLIT_HORIZONTALLY, DIVISION_MENU_EDIT_BOTTOM_EDGE, self.OnMenu)
960
+
961
+ def SetClientData(self, data):
962
+ self._clientData = data
963
+
964
+ def GetClientData(self):
965
+ return self._clientData
966
+
967
+ def OnMenu(self, event):
968
+ division = self.GetClientData()
969
+ if event.GetId() == DIVISION_MENU_SPLIT_HORIZONTALLY:
970
+ division.Divide(wx.HORIZONTAL)
971
+ elif event.GetId() == DIVISION_MENU_SPLIT_VERTICALLY:
972
+ division.Divide(wx.VERTICAL)
973
+ elif event.GetId() == DIVISION_MENU_EDIT_LEFT_EDGE:
974
+ division.EditEdge(DIVISION_SIDE_LEFT)
975
+ elif event.GetId() == DIVISION_MENU_EDIT_TOP_EDGE:
976
+ division.EditEdge(DIVISION_SIDE_TOP)
977
+
978
+
979
+
980
+ class DivisionShape(CompositeShape):
981
+ """
982
+ A :class:`DivisionShape` class is a composite with special properties,
983
+ to be used for containment. It's a subdivision of a container.
984
+ A containing node image consists of a composite with a main child shape
985
+ such as rounded rectangle, plus a list of division objects.
986
+ It needs to be a composite because a division contains pieces
987
+ of diagram.
988
+
989
+ :note: A container has at least one wxDivisionShape for consistency.
990
+ This can be subdivided, so it turns into two objects, then each of
991
+ these can be subdivided, etc.
992
+
993
+ """
994
+ def __init__(self):
995
+ """
996
+ Default class constructor.
997
+ """
998
+ CompositeShape.__init__(self)
999
+ self.SetSensitivityFilter(OP_CLICK_LEFT | OP_CLICK_RIGHT | OP_DRAG_RIGHT)
1000
+ self.SetCentreResize(False)
1001
+ self.SetAttachmentMode(True)
1002
+ self._leftSide = None
1003
+ self._rightSide = None
1004
+ self._topSide = None
1005
+ self._bottomSide = None
1006
+ self._handleSide = DIVISION_SIDE_NONE
1007
+ self._leftSidePen = wx.BLACK_PEN
1008
+ self._topSidePen = wx.BLACK_PEN
1009
+ self._leftSideColour = "BLACK"
1010
+ self._topSideColour = "BLACK"
1011
+ self._leftSideStyle = "Solid"
1012
+ self._topSideStyle = "Solid"
1013
+ self.ClearRegions()
1014
+
1015
+ def SetLeftSide(self, shape):
1016
+ """Set the the division on the left side of this division."""
1017
+ self._leftSide = shape
1018
+
1019
+ def SetTopSide(self, shape):
1020
+ """Set the the division on the top side of this division."""
1021
+ self._topSide = shape
1022
+
1023
+ def SetRightSide(self, shape):
1024
+ """Set the the division on the right side of this division."""
1025
+ self._rightSide = shape
1026
+
1027
+ def SetBottomSide(self, shape):
1028
+ """Set the the division on the bottom side of this division."""
1029
+ self._bottomSide = shape
1030
+
1031
+ def GetLeftSide(self):
1032
+ """Return the division on the left side of this division."""
1033
+ return self._leftSide
1034
+
1035
+ def GetTopSide(self):
1036
+ """Return the division on the top side of this division."""
1037
+ return self._topSide
1038
+
1039
+ def GetRightSide(self):
1040
+ """Return the division on the right side of this division."""
1041
+ return self._rightSide
1042
+
1043
+ def GetBottomSide(self):
1044
+ """Return the division on the bottom side of this division."""
1045
+ return self._bottomSide
1046
+
1047
+ def SetHandleSide(self, side):
1048
+ """
1049
+ Sets the side which the handle appears on.
1050
+
1051
+ :param `side`: Either DIVISION_SIDE_LEFT or DIVISION_SIDE_TOP.
1052
+
1053
+ """
1054
+ self._handleSide = side
1055
+
1056
+ def GetHandleSide(self):
1057
+ """Return the side which the handle appears on."""
1058
+ return self._handleSide
1059
+
1060
+ def SetLeftSidePen(self, pen):
1061
+ """Set the colour for drawing the left side of the division."""
1062
+ self._leftSidePen = pen
1063
+
1064
+ def SetTopSidePen(self, pen):
1065
+ """Set the colour for drawing the top side of the division."""
1066
+ self._topSidePen = pen
1067
+
1068
+ def GetLeftSidePen(self):
1069
+ """Return the pen used for drawing the left side of the division."""
1070
+ return self._leftSidePen
1071
+
1072
+ def GetTopSidePen(self):
1073
+ """Return the pen used for drawing the top side of the division."""
1074
+ return self._topSidePen
1075
+
1076
+ def GetLeftSideColour(self):
1077
+ """Return the colour used for drawing the left side of the division."""
1078
+ return self._leftSideColour
1079
+
1080
+ def GetTopSideColour(self):
1081
+ """Return the colour used for drawing the top side of the division."""
1082
+ return self._topSideColour
1083
+
1084
+ def SetLeftSideColour(self, colour):
1085
+ """Set the colour for drawing the left side of the division."""
1086
+ self._leftSideColour = colour
1087
+
1088
+ def SetTopSideColour(self, colour):
1089
+ """Set the colour for drawing the top side of the division."""
1090
+ self._topSideColour = colour
1091
+
1092
+ def GetLeftSideStyle(self):
1093
+ """Return the style used for the left side of the division."""
1094
+ return self._leftSideStyle
1095
+
1096
+ def GetTopSideStyle(self):
1097
+ """Return the style used for the top side of the division."""
1098
+ return self._topSideStyle
1099
+
1100
+ def SetLeftSideStyle(self, style):
1101
+ """
1102
+ Set the left side style.
1103
+
1104
+ :param `style`: valid values ???
1105
+
1106
+ """
1107
+ self._leftSideStyle = style
1108
+
1109
+ def SetTopSideStyle(self, style):
1110
+ """
1111
+ Set the top side style.
1112
+
1113
+ :param `style`: valid values ???
1114
+
1115
+ """
1116
+ self._lefttopStyle = style
1117
+
1118
+ def OnDraw(self, dc):
1119
+ """The draw handler."""
1120
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
1121
+ dc.SetBackgroundMode(wx.TRANSPARENT)
1122
+
1123
+ x1 = self.GetX() - self.GetWidth() / 2.0
1124
+ y1 = self.GetY() - self.GetHeight() / 2.0
1125
+ x2 = self.GetX() + self.GetWidth() / 2.0
1126
+ y2 = self.GetY() + self.GetHeight() / 2.0
1127
+
1128
+ # Should subtract 1 pixel if drawing under Windows
1129
+ if sys.platform[:3] == "win":
1130
+ y2 -= 1
1131
+
1132
+ if self._leftSide:
1133
+ dc.SetPen(self._leftSidePen)
1134
+ dc.DrawLine(int(x1), int(y2), int(x1), int(y1))
1135
+
1136
+ if self._topSide:
1137
+ dc.SetPen(self._topSidePen)
1138
+ dc.DrawLine(int(x1), int(y1), int(x2), int(y1))
1139
+
1140
+ # For testing purposes, draw a rectangle so we know
1141
+ # how big the division is.
1142
+ #dc.SetBrush(wx.RED_BRUSH)
1143
+ #dc.DrawRectangle(x1, y1, self.GetWidth(), self.GetHeight())
1144
+
1145
+ def OnDrawContents(self, dc):
1146
+ """The draw contents handler."""
1147
+ CompositeShape.OnDrawContents(self, dc)
1148
+
1149
+ def OnMovePre(self, dc, x, y, oldx, oldy, display = True):
1150
+ """The move 'pre' handler."""
1151
+ diffX = x - oldx
1152
+ diffY = y - oldy
1153
+ for object in self._children:
1154
+ object.Erase(dc)
1155
+ object.Move(dc, object.GetX() + diffX, object.GetY() + diffY, display)
1156
+ return True
1157
+
1158
+ def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
1159
+ """The drag left handler."""
1160
+ if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
1161
+ if self._parent:
1162
+ hit = self._parent.HitTest(x, y)
1163
+ if hit:
1164
+ attachment, dist = hit
1165
+ self._parent.GetEventHandler().OnDragLeft(draw, x, y, keys, attachment)
1166
+ return
1167
+ Shape.OnDragLeft(self, draw, x, y, keys, attachment)
1168
+
1169
+ def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
1170
+ """The begin drag left handler."""
1171
+ if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
1172
+ if self._parent:
1173
+ hit = self._parent.HitTest(x, y)
1174
+ if hit:
1175
+ attachment, dist = hit
1176
+ self._parent.GetEventHandler().OnBeginDragLeft(x, y, keys, attachment)
1177
+ return
1178
+ Shape.OnBeginDragLeft(x, y, keys, attachment)
1179
+
1180
+ def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
1181
+ """The end drag left handler."""
1182
+ if self._canvas.HasCapture():
1183
+ self._canvas.ReleaseMouse()
1184
+ if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
1185
+ if self._parent:
1186
+ hit = self._parent.HitTest(x, y)
1187
+ if hit:
1188
+ attachment, dist = hit
1189
+ self._parent.GetEventHandler().OnEndDragLeft(x, y, keys, attachment)
1190
+ return
1191
+
1192
+ dc = wx.MemoryDC()
1193
+ dc.SelectObject(self.GetCanvas().GetBuffer())
1194
+ self.GetCanvas().PrepareDC(dc)
1195
+ dc.SetLogicalFunction(wx.COPY)
1196
+
1197
+ self._xpos, self._ypos = self._canvas.Snap(self._xpos, self._ypos)
1198
+ self.GetEventHandler().OnMovePre(dc, x, y, self._oldX, self._oldY)
1199
+
1200
+ self.ResetControlPoints()
1201
+ self.Draw(dc)
1202
+ self.MoveLinks(dc)
1203
+ self.GetEventHandler().OnDrawControlPoints(dc)
1204
+
1205
+ if self._canvas and not self._canvas.GetQuickEditMode():
1206
+ self._canvas.Redraw(dc)
1207
+
1208
+ def SetSize(self, w, h, recursive = True):
1209
+ """
1210
+ Set the size.
1211
+
1212
+ :param `w`: the width
1213
+ :param `h`: the height
1214
+ :param `recursive`: `True` recurse all children
1215
+
1216
+ """
1217
+ self._width = w
1218
+ self._height = h
1219
+ RectangleShape.SetSize(self, w, h, recursive)
1220
+
1221
+ def CalculateSize(self):
1222
+ """not implemented???"""
1223
+ pass
1224
+
1225
+ # Experimental
1226
+ def OnRightClick(self, x, y, keys = 0, attachment = 0):
1227
+ """The right click handler."""
1228
+ if keys & KEY_CTRL:
1229
+ self.PopupMenu(x, y)
1230
+ else:
1231
+ if self._parent:
1232
+ hit = self._parent.HitTest(x, y)
1233
+ if hit:
1234
+ attachment, dist = hit
1235
+ self._parent.GetEventHandler().OnRightClick(x, y, keys, attachment)
1236
+
1237
+ def Divide(self, direction):
1238
+ """Divide this division into two further divisions.
1239
+
1240
+ :param `direction`: `wx.HORIZONTAL` for horizontal or `wx.VERTICAL` for
1241
+ vertical division.
1242
+
1243
+ """
1244
+ # Calculate existing top-left, bottom-right
1245
+ x1 = self.GetX() - self.GetWidth() / 2.0
1246
+ y1 = self.GetY() - self.GetHeight() / 2.0
1247
+
1248
+ compositeParent = self.GetParent()
1249
+ oldWidth = self.GetWidth()
1250
+ oldHeight = self.GetHeight()
1251
+ if self.Selected():
1252
+ self.Select(False)
1253
+
1254
+ dc = wx.MemoryDC()
1255
+ dc.SelectObject(self.GetCanvas().GetBuffer())
1256
+ self.GetCanvas().PrepareDC(dc)
1257
+
1258
+ if direction == wx.VERTICAL:
1259
+ # Dividing vertically means notionally putting a horizontal
1260
+ # line through it.
1261
+ # Break existing piece into two.
1262
+ newXPos1 = self.GetX()
1263
+ newYPos1 = y1 + self.GetHeight() / 4.0
1264
+ newXPos2 = self.GetX()
1265
+ newYPos2 = y1 + 3 * self.GetHeight() / 4.0
1266
+ newDivision = compositeParent.OnCreateDivision()
1267
+ newDivision.Show(True)
1268
+
1269
+ self.Erase(dc)
1270
+
1271
+ # Anything adjoining the bottom of this division now adjoins the
1272
+ # bottom of the new division.
1273
+ for obj in compositeParent.GetDivisions():
1274
+ if obj.GetTopSide() == self:
1275
+ obj.SetTopSide(newDivision)
1276
+
1277
+ newDivision.SetTopSide(self)
1278
+ newDivision.SetBottomSide(self._bottomSide)
1279
+ newDivision.SetLeftSide(self._leftSide)
1280
+ newDivision.SetRightSide(self._rightSide)
1281
+ self._bottomSide = newDivision
1282
+
1283
+ compositeParent.GetDivisions().append(newDivision)
1284
+
1285
+ # CHANGE: Need to insert this division at start of divisions in the
1286
+ # object list, because e.g.:
1287
+ # 1) Add division
1288
+ # 2) Add contained object
1289
+ # 3) Add division
1290
+ # Division is now receiving mouse events _before_ the contained
1291
+ # object, because it was added last (on top of all others)
1292
+
1293
+ # Add after the image that visualizes the container
1294
+ compositeParent.AddChild(newDivision, compositeParent.FindContainerImage())
1295
+
1296
+ self._handleSide = DIVISION_SIDE_BOTTOM
1297
+ newDivision.SetHandleSide(DIVISION_SIDE_TOP)
1298
+
1299
+ self.SetSize(oldWidth, oldHeight / 2.0)
1300
+ self.Move(dc, newXPos1, newYPos1)
1301
+
1302
+ newDivision.SetSize(oldWidth, oldHeight / 2.0)
1303
+ newDivision.Move(dc, newXPos2, newYPos2)
1304
+ else:
1305
+ # Dividing horizontally means notionally putting a vertical line
1306
+ # through it.
1307
+ # Break existing piece into two.
1308
+ newXPos1 = x1 + self.GetWidth() / 4.0
1309
+ newYPos1 = self.GetY()
1310
+ newXPos2 = x1 + 3 * self.GetWidth() / 4.0
1311
+ newYPos2 = self.GetY()
1312
+ newDivision = compositeParent.OnCreateDivision()
1313
+ newDivision.Show(True)
1314
+
1315
+ self.Erase(dc)
1316
+
1317
+ # Anything adjoining the left of this division now adjoins the
1318
+ # left of the new division.
1319
+ for obj in compositeParent.GetDivisions():
1320
+ if obj.GetLeftSide() == self:
1321
+ obj.SetLeftSide(newDivision)
1322
+
1323
+ newDivision.SetTopSide(self._topSide)
1324
+ newDivision.SetBottomSide(self._bottomSide)
1325
+ newDivision.SetLeftSide(self)
1326
+ newDivision.SetRightSide(self._rightSide)
1327
+ self._rightSide = newDivision
1328
+
1329
+ compositeParent.GetDivisions().append(newDivision)
1330
+ compositeParent.AddChild(newDivision, compositeParent.FindContainerImage())
1331
+
1332
+ self._handleSide = DIVISION_SIDE_RIGHT
1333
+ newDivision.SetHandleSide(DIVISION_SIDE_LEFT)
1334
+
1335
+ self.SetSize(oldWidth / 2.0, oldHeight)
1336
+ self.Move(dc, newXPos1, newYPos1)
1337
+
1338
+ newDivision.SetSize(oldWidth / 2.0, oldHeight)
1339
+ newDivision.Move(dc, newXPos2, newYPos2)
1340
+
1341
+ if compositeParent.Selected():
1342
+ compositeParent.DeleteControlPoints(dc)
1343
+ compositeParent.MakeControlPoints()
1344
+ compositeParent.MakeMandatoryControlPoints()
1345
+
1346
+ compositeParent.Draw(dc)
1347
+ return True
1348
+
1349
+ def MakeControlPoints(self):
1350
+ """Make control points."""
1351
+ self.MakeMandatoryControlPoints()
1352
+
1353
+ def MakeMandatoryControlPoints(self):
1354
+ """Make mandatory control points."""
1355
+ maxX, maxY = self.GetBoundingBoxMax()
1356
+ x = y = 0.0
1357
+ direction = 0
1358
+
1359
+ if self._handleSide == DIVISION_SIDE_LEFT:
1360
+ x = -maxX / 2.0
1361
+ direction = CONTROL_POINT_HORIZONTAL
1362
+ elif self._handleSide == DIVISION_SIDE_TOP:
1363
+ y = -maxY / 2.0
1364
+ direction = CONTROL_POINT_VERTICAL
1365
+ elif self._handleSide == DIVISION_SIDE_RIGHT:
1366
+ x = maxX / 2.0
1367
+ direction = CONTROL_POINT_HORIZONTAL
1368
+ elif self._handleSide == DIVISION_SIDE_BOTTOM:
1369
+ y = maxY / 2.0
1370
+ direction = CONTROL_POINT_VERTICAL
1371
+
1372
+ if self._handleSide != DIVISION_SIDE_NONE:
1373
+ control = DivisionControlPoint(self._canvas, self, CONTROL_POINT_SIZE, x, y, direction)
1374
+ self._canvas.AddShape(control)
1375
+ self._controlPoints.append(control)
1376
+
1377
+ def ResetControlPoints(self):
1378
+ """Reset control points."""
1379
+ self.ResetMandatoryControlPoints()
1380
+
1381
+ def ResetMandatoryControlPoints(self):
1382
+ """Reset mandatory control points."""
1383
+ if not self._controlPoints:
1384
+ return
1385
+
1386
+ maxX, maxY = self.GetBoundingBoxMax()
1387
+
1388
+ node = self._controlPoints[0]
1389
+
1390
+ if self._handleSide == DIVISION_SIDE_LEFT and node:
1391
+ node._xoffset = -maxX / 2.0
1392
+ node._yoffset = 0.0
1393
+
1394
+ if self._handleSide == DIVISION_SIDE_TOP and node:
1395
+ node._xoffset = 0.0
1396
+ node._yoffset = -maxY / 2.0
1397
+
1398
+ if self._handleSide == DIVISION_SIDE_RIGHT and node:
1399
+ node._xoffset = maxX / 2.0
1400
+ node._yoffset = 0.0
1401
+
1402
+ if self._handleSide == DIVISION_SIDE_BOTTOM and node:
1403
+ node._xoffset = 0.0
1404
+ node._yoffset = maxY / 2.0
1405
+
1406
+ def AdjustLeft(self, left, test):
1407
+ """
1408
+ Adjust a side.
1409
+
1410
+ :param `left`: desired left position ???
1411
+ :param `test`: if `True` just a test
1412
+ :returns: `False` if it's not physically possible to adjust it to
1413
+ this point.
1414
+ """
1415
+ x2 = self.GetX() + self.GetWidth() / 2.0
1416
+
1417
+ if left >= x2:
1418
+ return False
1419
+
1420
+ if test:
1421
+ return True
1422
+
1423
+ newW = x2 - left
1424
+ newX = left + newW / 2.0
1425
+ self.SetSize(newW, self.GetHeight())
1426
+
1427
+ dc = wx.MemoryDC()
1428
+ dc.SelectObject(self.GetCanvas().GetBuffer())
1429
+ self.GetCanvas().PrepareDC(dc)
1430
+
1431
+ self.Move(dc, newX, self.GetY())
1432
+ return True
1433
+
1434
+ def AdjustRight(self, right, test):
1435
+ """
1436
+ Adjust a side.
1437
+
1438
+ :param `right`: desired right position ???
1439
+ :param `test`: if `True` just a test
1440
+ :returns: `False` if it's not physically possible to adjust it to
1441
+ this point.
1442
+
1443
+ """
1444
+ x1 = self.GetX() - self.GetWidth() / 2.0
1445
+
1446
+ if right <= x1:
1447
+ return False
1448
+
1449
+ if test:
1450
+ return True
1451
+
1452
+ newW = right - x1
1453
+ newX = x1 + newW / 2.0
1454
+ self.SetSize(newW, self.GetHeight())
1455
+
1456
+ dc = wx.MemoryDC()
1457
+ dc.SelectObject(self.GetCanvas().GetBuffer())
1458
+ self.GetCanvas().PrepareDC(dc)
1459
+
1460
+ self.Move(dc, newX, self.GetY())
1461
+ return True
1462
+
1463
+ def AdjustTop(self, top, test):
1464
+ """
1465
+ Adjust a side.
1466
+
1467
+ :param `top`: desired top position ???
1468
+ :param `test`: if `True` just a test
1469
+ :returns: `False` if it's not physically possible to adjust it to
1470
+ this point.
1471
+
1472
+ """
1473
+ y1 = self.GetY() - self.GetHeight() / 2.0
1474
+
1475
+ if top <= y1:
1476
+ return False
1477
+
1478
+ if test:
1479
+ return True
1480
+
1481
+ newH = top - y1
1482
+ newY = y1 + newH / 2.0
1483
+ self.SetSize(self.GetWidth(), newH)
1484
+
1485
+ dc = wx.MemoryDC()
1486
+ dc.SelectObject(self.GetCanvas().GetBuffer())
1487
+ self.GetCanvas().PrepareDC(dc)
1488
+
1489
+ self.Move(dc, self.GetX(), newY)
1490
+ return True
1491
+
1492
+ # Resize adjoining divisions.
1493
+
1494
+ # Behaviour should be as follows:
1495
+ # If right edge moves, find all objects whose left edge
1496
+ # adjoins this object, and move left edge accordingly.
1497
+ # If left..., move ... right.
1498
+ # If top..., move ... bottom.
1499
+ # If bottom..., move top.
1500
+ # If size goes to zero or end position is other side of start position,
1501
+ # resize to original size and return.
1502
+ #
1503
+ def ResizeAdjoining(self, side, newPos, test):
1504
+ """
1505
+ Resize adjoining divisions at the given side.
1506
+
1507
+ :param `side`: can be one of
1508
+
1509
+ ======================= =======================
1510
+ Side option Description
1511
+ ======================= =======================
1512
+ `DIVISION_SIDE_NONE` no side
1513
+ `DIVISION_SIDE_LEFT` Left side
1514
+ `DIVISION_SIDE_TOP` Top side
1515
+ `DIVISION_SIDE_RIGHT` Right side
1516
+ `DIVISION_SIDE_BOTTOM` Bottom side
1517
+ ======================= =======================
1518
+
1519
+ :param `newPos`: new position
1520
+ :param `test`: if `True`, just see whether it's possible for each
1521
+ adjoining region, returning `False` if it's not.
1522
+
1523
+ """
1524
+ divisionParent = self.GetParent()
1525
+ for division in divisionParent.GetDivisions():
1526
+ if side == DIVISION_SIDE_LEFT:
1527
+ if division._rightSide == self:
1528
+ success = division.AdjustRight(newPos, test)
1529
+ if not success and test:
1530
+ return False
1531
+ elif side == DIVISION_SIDE_TOP:
1532
+ if division._bottomSide == self:
1533
+ success = division.AdjustBottom(newPos, test)
1534
+ if not success and test:
1535
+ return False
1536
+ elif side == DIVISION_SIDE_RIGHT:
1537
+ if division._leftSide == self:
1538
+ success = division.AdjustLeft(newPos, test)
1539
+ if not success and test:
1540
+ return False
1541
+ elif side == DIVISION_SIDE_BOTTOM:
1542
+ if division._topSide == self:
1543
+ success = division.AdjustTop(newPos, test)
1544
+ if not success and test:
1545
+ return False
1546
+ return True
1547
+
1548
+ def EditEdge(self, side):
1549
+ print("EditEdge() not implemented.")
1550
+
1551
+ def PopupMenu(self, x, y):
1552
+ """Popup menu handler."""
1553
+ menu = PopupDivisionMenu()
1554
+ menu.SetClientData(self)
1555
+ if self._leftSide:
1556
+ menu.Enable(DIVISION_MENU_EDIT_LEFT_EDGE, True)
1557
+ else:
1558
+ menu.Enable(DIVISION_MENU_EDIT_LEFT_EDGE, False)
1559
+ if self._topSide:
1560
+ menu.Enable(DIVISION_MENU_EDIT_TOP_EDGE, True)
1561
+ else:
1562
+ menu.Enable(DIVISION_MENU_EDIT_TOP_EDGE, False)
1563
+
1564
+ x1, y1 = self._canvas.GetViewStart()
1565
+ unit_x, unit_y = self._canvas.GetScrollPixelsPerUnit()
1566
+
1567
+ dc = wx.MemoryDC()
1568
+ dc.SelectObject(self.GetCanvas().GetBuffer())
1569
+ self.GetCanvas().PrepareDC(dc)
1570
+
1571
+ mouse_x = dc.LogicalToDeviceX(x - x1 * unit_x)
1572
+ mouse_y = dc.LogicalToDeviceY(y - y1 * unit_y)
1573
+
1574
+ self._canvas.PopupMenu(menu, (mouse_x, mouse_y))
1575
+
1576
+