wxPython-zombie 3.1.5.8__cp313-cp313-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 (1175) hide show
  1. wx/__init__.py +22 -0
  2. wx/__version__.py +9 -0
  3. wx/_adv.cp313-win_amd64.pyd +0 -0
  4. wx/_aui.cp313-win_amd64.pyd +0 -0
  5. wx/_core.cp313-win_amd64.pyd +0 -0
  6. wx/_dataview.cp313-win_amd64.pyd +0 -0
  7. wx/_glcanvas.cp313-win_amd64.pyd +0 -0
  8. wx/_grid.cp313-win_amd64.pyd +0 -0
  9. wx/_html.cp313-win_amd64.pyd +0 -0
  10. wx/_html2.cp313-win_amd64.pyd +0 -0
  11. wx/_media.cp313-win_amd64.pyd +0 -0
  12. wx/_msw.cp313-win_amd64.pyd +0 -0
  13. wx/_propgrid.cp313-win_amd64.pyd +0 -0
  14. wx/_ribbon.cp313-win_amd64.pyd +0 -0
  15. wx/_richtext.cp313-win_amd64.pyd +0 -0
  16. wx/_stc.cp313-win_amd64.pyd +0 -0
  17. wx/_xml.cp313-win_amd64.pyd +0 -0
  18. wx/_xrc.cp313-win_amd64.pyd +0 -0
  19. wx/adv.py +124 -0
  20. wx/adv.pyi +5182 -0
  21. wx/aui.py +77 -0
  22. wx/aui.pyi +3655 -0
  23. wx/core.py +3540 -0
  24. wx/core.pyi +50592 -0
  25. wx/dataview.py +173 -0
  26. wx/dataview.pyi +3491 -0
  27. wx/demo/AUI_DockingWindowMgr.py +1154 -0
  28. wx/demo/AUI_MDI.py +117 -0
  29. wx/demo/AUI_Notebook.py +58 -0
  30. wx/demo/About.py +75 -0
  31. wx/demo/AboutBox.py +75 -0
  32. wx/demo/ActiveXWrapper_Acrobat.py +132 -0
  33. wx/demo/ActiveXWrapper_IE.py +187 -0
  34. wx/demo/ActiveX_FlashWindow.py +107 -0
  35. wx/demo/ActiveX_IEHtmlWindow.py +242 -0
  36. wx/demo/ActiveX_PDFWindow.py +204 -0
  37. wx/demo/ActivityIndicator.py +80 -0
  38. wx/demo/AddPrivateFont.py +116 -0
  39. wx/demo/AdjustChannels.py +178 -0
  40. wx/demo/AlphaDrawing.py +77 -0
  41. wx/demo/AnalogClock.py +144 -0
  42. wx/demo/AnimationCtrl.py +104 -0
  43. wx/demo/ArtProvider.py +893 -0
  44. wx/demo/BannerWindow.py +1 -0
  45. wx/demo/BitmapButton.py +87 -0
  46. wx/demo/BitmapComboBox.py +63 -0
  47. wx/demo/BitmapFromBuffer.py +140 -0
  48. wx/demo/Button.py +77 -0
  49. wx/demo/Cairo.py +197 -0
  50. wx/demo/Cairo_Snippets.py +135 -0
  51. wx/demo/Calendar.py +660 -0
  52. wx/demo/CalendarCtrl.py +122 -0
  53. wx/demo/CheckBox.py +74 -0
  54. wx/demo/CheckListBox.py +79 -0
  55. wx/demo/CheckListCtrl.py +99 -0
  56. wx/demo/Choice.py +55 -0
  57. wx/demo/Choicebook.py +80 -0
  58. wx/demo/CollapsibleHeaderCtrl.py +85 -0
  59. wx/demo/CollapsiblePane.py +126 -0
  60. wx/demo/ColorPanel.py +19 -0
  61. wx/demo/ColourDB.py +203 -0
  62. wx/demo/ColourDialog.py +76 -0
  63. wx/demo/ColourSelect.py +119 -0
  64. wx/demo/ComboBox.py +111 -0
  65. wx/demo/ComboCtrl.py +153 -0
  66. wx/demo/ComboTreeBox.py +71 -0
  67. wx/demo/CommandLinkButton.py +50 -0
  68. wx/demo/ContextHelp.py +112 -0
  69. wx/demo/Cursor.py +336 -0
  70. wx/demo/CustomDragAndDrop.py +353 -0
  71. wx/demo/DVC_CustomRenderer.py +204 -0
  72. wx/demo/DVC_DataViewModel.py +365 -0
  73. wx/demo/DVC_IndexListModel.py +257 -0
  74. wx/demo/DVC_ListCtrl.py +69 -0
  75. wx/demo/DVC_TreeCtrl.py +76 -0
  76. wx/demo/DatePickerCtrl.py +68 -0
  77. wx/demo/DelayedResult.py +239 -0
  78. wx/demo/Dialog.py +169 -0
  79. wx/demo/DialogUnits.py +128 -0
  80. wx/demo/DirDialog.py +58 -0
  81. wx/demo/DragAndDrop.py +265 -0
  82. wx/demo/DragImage.py +316 -0
  83. wx/demo/DragScroller.py +59 -0
  84. wx/demo/DrawXXXList.py +436 -0
  85. wx/demo/DynamicSashWindow.py +177 -0
  86. wx/demo/EditableListBox.py +101 -0
  87. wx/demo/Editor.py +70 -0
  88. wx/demo/EventManager.py +291 -0
  89. wx/demo/ExpandoTextCtrl.py +164 -0
  90. wx/demo/FancyText.py +83 -0
  91. wx/demo/FileBrowseButton.py +100 -0
  92. wx/demo/FileCtrl.py +97 -0
  93. wx/demo/FileDialog.py +144 -0
  94. wx/demo/FileHistory.py +140 -0
  95. wx/demo/FindReplaceDialog.py +123 -0
  96. wx/demo/FloatCanvas.py +1959 -0
  97. wx/demo/FontDialog.py +142 -0
  98. wx/demo/FontEnumerator.py +82 -0
  99. wx/demo/Frame.py +85 -0
  100. wx/demo/GLCanvas.py +371 -0
  101. wx/demo/Gauge.py +66 -0
  102. wx/demo/GenericButtons.py +185 -0
  103. wx/demo/GenericCheckBox.py +65 -0
  104. wx/demo/GenericDirCtrl.py +74 -0
  105. wx/demo/GetMouseState.py +159 -0
  106. wx/demo/GraphicsContext.py +236 -0
  107. wx/demo/GraphicsGradient.py +281 -0
  108. wx/demo/Grid.py +95 -0
  109. wx/demo/GridBagSizer.py +170 -0
  110. wx/demo/GridCustEditor.py +247 -0
  111. wx/demo/GridCustTable.py +170 -0
  112. wx/demo/GridDragAndDrop.py +102 -0
  113. wx/demo/GridDragable.py +206 -0
  114. wx/demo/GridEnterHandler.py +66 -0
  115. wx/demo/GridHugeTable.py +89 -0
  116. wx/demo/GridLabelRenderer.py +114 -0
  117. wx/demo/GridSimple.py +270 -0
  118. wx/demo/GridStdEdRend.py +186 -0
  119. wx/demo/Grid_MegaExample.py +490 -0
  120. wx/demo/HTML2_WebView.py +183 -0
  121. wx/demo/HtmlWindow.py +232 -0
  122. wx/demo/I18N.py +237 -0
  123. wx/demo/Image.py +338 -0
  124. wx/demo/ImageAlpha.py +87 -0
  125. wx/demo/ImageBrowser.py +70 -0
  126. wx/demo/ImageFromStream.py +49 -0
  127. wx/demo/Img2PyArtProvider.py +99 -0
  128. wx/demo/InfoBar.py +127 -0
  129. wx/demo/IntCtrl.py +343 -0
  130. wx/demo/ItemsPicker.py +108 -0
  131. wx/demo/Joystick.py +1083 -0
  132. wx/demo/KeyEvents.py +428 -0
  133. wx/demo/LEDNumberCtrl.py +121 -0
  134. wx/demo/LayoutAnchors.py +258 -0
  135. wx/demo/LayoutConstraints.py +149 -0
  136. wx/demo/Layoutf.py +69 -0
  137. wx/demo/ListBox.py +164 -0
  138. wx/demo/ListCtrl.py +538 -0
  139. wx/demo/ListCtrl_edit.py +155 -0
  140. wx/demo/ListCtrl_virtual.py +145 -0
  141. wx/demo/Listbook.py +104 -0
  142. wx/demo/MDIDemo.py +86 -0
  143. wx/demo/MDISashDemo.py +152 -0
  144. wx/demo/MDIWindows.py +66 -0
  145. wx/demo/Main.py +2768 -0
  146. wx/demo/Mask.py +137 -0
  147. wx/demo/MaskedEditControls.py +648 -0
  148. wx/demo/MaskedNumCtrl.py +359 -0
  149. wx/demo/MediaCtrl.py +190 -0
  150. wx/demo/Menu.py +322 -0
  151. wx/demo/MessageDialog.py +54 -0
  152. wx/demo/MimeTypesManager.py +354 -0
  153. wx/demo/MiniFrame.py +67 -0
  154. wx/demo/MouseGestures.py +198 -0
  155. wx/demo/MultiChoiceDialog.py +59 -0
  156. wx/demo/MultiSash.py +95 -0
  157. wx/demo/MultiSplitterWindow.py +168 -0
  158. wx/demo/MultipleChoiceDialog.py +101 -0
  159. wx/demo/Notebook.py +134 -0
  160. wx/demo/NotificationMessage.py +61 -0
  161. wx/demo/OGL.py +433 -0
  162. wx/demo/Overlay.py +209 -0
  163. wx/demo/OwnerDrawnComboBox.py +152 -0
  164. wx/demo/PDFViewer.py +109 -0
  165. wx/demo/PageSetupDialog.py +70 -0
  166. wx/demo/PenAndBrushStyles.py +208 -0
  167. wx/demo/Pickers.py +120 -0
  168. wx/demo/PlateButton.py +430 -0
  169. wx/demo/PopupControl.py +99 -0
  170. wx/demo/PopupMenu.py +156 -0
  171. wx/demo/PopupWindow.py +227 -0
  172. wx/demo/PrintDialog.py +60 -0
  173. wx/demo/PrintFramework.py +227 -0
  174. wx/demo/Process.py +168 -0
  175. wx/demo/ProgressDialog.py +87 -0
  176. wx/demo/PropertyGrid.py +1045 -0
  177. wx/demo/PropertySheetDialog.py +231 -0
  178. wx/demo/PseudoDC.py +350 -0
  179. wx/demo/PyColourChooser.py +60 -0
  180. wx/demo/PyCrust.py +21 -0
  181. wx/demo/PyPlot.py +83 -0
  182. wx/demo/PyShell.py +22 -0
  183. wx/demo/PythonEvents.py +109 -0
  184. wx/demo/README.txt +7 -0
  185. wx/demo/RadioBox.py +67 -0
  186. wx/demo/RadioButton.py +127 -0
  187. wx/demo/RawBitmapAccess.py +208 -0
  188. wx/demo/RearrangeDialog.py +160 -0
  189. wx/demo/RendererNative.py +170 -0
  190. wx/demo/ResizeWidget.py +76 -0
  191. wx/demo/RichMessageDialog.py +85 -0
  192. wx/demo/RichTextCtrl.py +732 -0
  193. wx/demo/RichToolTip.py +145 -0
  194. wx/demo/SVGImage_Bitmap.py +130 -0
  195. wx/demo/SVGImage_Render.py +138 -0
  196. wx/demo/SashWindow.py +151 -0
  197. wx/demo/ScrolledMessageDialog.py +52 -0
  198. wx/demo/ScrolledPanel.py +124 -0
  199. wx/demo/ScrolledWindow.py +260 -0
  200. wx/demo/SearchCtrl.py +115 -0
  201. wx/demo/ShapedWindow.py +145 -0
  202. wx/demo/Simplebook.py +202 -0
  203. wx/demo/SingleChoiceDialog.py +56 -0
  204. wx/demo/SizedControls.py +433 -0
  205. wx/demo/Sizers.py +609 -0
  206. wx/demo/Slider.py +52 -0
  207. wx/demo/Sound.py +95 -0
  208. wx/demo/SpinButton.py +63 -0
  209. wx/demo/SpinCtrl.py +56 -0
  210. wx/demo/SpinCtrlDouble.py +42 -0
  211. wx/demo/SplitTree.py +146 -0
  212. wx/demo/SplitterWindow.py +62 -0
  213. wx/demo/StandardPaths.py +113 -0
  214. wx/demo/StaticBitmap.py +55 -0
  215. wx/demo/StaticBox.py +62 -0
  216. wx/demo/StaticText.py +69 -0
  217. wx/demo/StatusBar.py +144 -0
  218. wx/demo/StockButtons.py +113 -0
  219. wx/demo/StyledTextCtrl_1.py +303 -0
  220. wx/demo/StyledTextCtrl_2.py +410 -0
  221. wx/demo/SystemSettings.py +333 -0
  222. wx/demo/TablePrint.py +215 -0
  223. wx/demo/TestTable.txt +38 -0
  224. wx/demo/TextCtrl.py +187 -0
  225. wx/demo/TextEntryDialog.py +57 -0
  226. wx/demo/Threads.py +258 -0
  227. wx/demo/Throbber.py +250 -0
  228. wx/demo/Ticker.py +147 -0
  229. wx/demo/TimeCtrl.py +240 -0
  230. wx/demo/TimePickerCtrl.py +60 -0
  231. wx/demo/Timer.py +275 -0
  232. wx/demo/ToggleButton.py +54 -0
  233. wx/demo/ToolBar.py +249 -0
  234. wx/demo/ToolTip.py +71 -0
  235. wx/demo/Toolbook.py +111 -0
  236. wx/demo/TreeCtrl.py +199 -0
  237. wx/demo/TreeListCtrl.py +121 -0
  238. wx/demo/TreeMixin.py +269 -0
  239. wx/demo/Treebook.py +117 -0
  240. wx/demo/UIActionSimulator.py +151 -0
  241. wx/demo/URLDragAndDrop.py +130 -0
  242. wx/demo/Unicode.py +146 -0
  243. wx/demo/VListBox.py +176 -0
  244. wx/demo/Validator.py +237 -0
  245. wx/demo/Wizard.py +248 -0
  246. wx/demo/WrapSizer.py +115 -0
  247. wx/demo/XmlResource.py +80 -0
  248. wx/demo/XmlResourceHandler.py +199 -0
  249. wx/demo/XmlResourceSubclass.py +119 -0
  250. wx/demo/__init__.py +9 -0
  251. wx/demo/agw/AGWInfoBar.py +175 -0
  252. wx/demo/agw/AUI.py +3058 -0
  253. wx/demo/agw/AdvancedSplash.py +59 -0
  254. wx/demo/agw/AquaButton.py +146 -0
  255. wx/demo/agw/BalloonTip.py +378 -0
  256. wx/demo/agw/ButtonPanel.py +890 -0
  257. wx/demo/agw/CubeColourDialog.py +83 -0
  258. wx/demo/agw/CustomTreeCtrl.py +2167 -0
  259. wx/demo/agw/Example1 +67 -0
  260. wx/demo/agw/Example2 +49 -0
  261. wx/demo/agw/FlatMenu.py +876 -0
  262. wx/demo/agw/FlatNotebook.py +994 -0
  263. wx/demo/agw/FloatSpin.py +475 -0
  264. wx/demo/agw/FoldPanelBar.py +953 -0
  265. wx/demo/agw/FourWaySplitter.py +300 -0
  266. wx/demo/agw/GenericMessageDialog.py +207 -0
  267. wx/demo/agw/GradientButton.py +156 -0
  268. wx/demo/agw/HyperLinkCtrl.py +144 -0
  269. wx/demo/agw/HyperTreeList.py +2660 -0
  270. wx/demo/agw/KnobCtrl.py +186 -0
  271. wx/demo/agw/LabelBook.py +567 -0
  272. wx/demo/agw/MacLargeDemo.py +360 -0
  273. wx/demo/agw/MultiDirDialog.py +117 -0
  274. wx/demo/agw/PeakMeter.py +194 -0
  275. wx/demo/agw/PersistentControls.py +589 -0
  276. wx/demo/agw/PieCtrl.py +206 -0
  277. wx/demo/agw/PyBusyInfo.py +64 -0
  278. wx/demo/agw/PyCollapsiblePane.py +308 -0
  279. wx/demo/agw/PyGauge.py +162 -0
  280. wx/demo/agw/PyProgress.py +155 -0
  281. wx/demo/agw/RibbonBar.py +925 -0
  282. wx/demo/agw/RulerCtrl.py +454 -0
  283. wx/demo/agw/ScrolledThumbnail.py +128 -0
  284. wx/demo/agw/ShapedButton.py +603 -0
  285. wx/demo/agw/ShortcutEditor.py +397 -0
  286. wx/demo/agw/SpeedMeter.py +668 -0
  287. wx/demo/agw/SuperToolTip.py +396 -0
  288. wx/demo/agw/ThumbDemoConfig.py +603 -0
  289. wx/demo/agw/ThumbnailCtrl.py +149 -0
  290. wx/demo/agw/ToasterBox.py +410 -0
  291. wx/demo/agw/UltimateListCtrl.py +80 -0
  292. wx/demo/agw/UltimateListIconDemo.py +908 -0
  293. wx/demo/agw/UltimateListListDemo.py +124 -0
  294. wx/demo/agw/UltimateReportDemo.py +1146 -0
  295. wx/demo/agw/UltimateVirtualDemo.py +207 -0
  296. wx/demo/agw/Windows7Explorer_Contents.py +368 -0
  297. wx/demo/agw/XLSGrid.py +238 -0
  298. wx/demo/agw/ZoomBar.py +230 -0
  299. wx/demo/agw/__demo__.py +183 -0
  300. wx/demo/agw/bitmaps/Explorer96.png +0 -0
  301. wx/demo/agw/bitmaps/Explorer96Flip40.png +0 -0
  302. wx/demo/agw/bitmaps/Folder96.png +0 -0
  303. wx/demo/agw/bitmaps/Folder96Flip40.png +0 -0
  304. wx/demo/agw/bitmaps/Monitor96.png +0 -0
  305. wx/demo/agw/bitmaps/Monitor96Flip40.png +0 -0
  306. wx/demo/agw/bitmaps/Music96.png +0 -0
  307. wx/demo/agw/bitmaps/Music96Flip40.png +0 -0
  308. wx/demo/agw/bitmaps/Photo96.png +0 -0
  309. wx/demo/agw/bitmaps/Photo96Flip40.png +0 -0
  310. wx/demo/agw/bitmaps/Search96.png +0 -0
  311. wx/demo/agw/bitmaps/Search96Flip40.png +0 -0
  312. wx/demo/agw/bitmaps/Wizard96.png +0 -0
  313. wx/demo/agw/bitmaps/Wizard96Flip40.png +0 -0
  314. wx/demo/agw/bitmaps/advancedsplash.png +0 -0
  315. wx/demo/agw/bitmaps/aquabutton.png +0 -0
  316. wx/demo/agw/bitmaps/aquachecked.ico +0 -0
  317. wx/demo/agw/bitmaps/aquaflagged.ico +0 -0
  318. wx/demo/agw/bitmaps/aquanotchecked.ico +0 -0
  319. wx/demo/agw/bitmaps/aquanotflagged.ico +0 -0
  320. wx/demo/agw/bitmaps/canada.gif +0 -0
  321. wx/demo/agw/bitmaps/checked.ico +0 -0
  322. wx/demo/agw/bitmaps/columns.png +0 -0
  323. wx/demo/agw/bitmaps/contexthelp-16.png +0 -0
  324. wx/demo/agw/bitmaps/contexthelp.png +0 -0
  325. wx/demo/agw/bitmaps/copy.png +0 -0
  326. wx/demo/agw/bitmaps/cut.png +0 -0
  327. wx/demo/agw/bitmaps/editcopy.png +0 -0
  328. wx/demo/agw/bitmaps/editcut.png +0 -0
  329. wx/demo/agw/bitmaps/editpaste.png +0 -0
  330. wx/demo/agw/bitmaps/empty_icon.png +0 -0
  331. wx/demo/agw/bitmaps/exit-16.png +0 -0
  332. wx/demo/agw/bitmaps/exit.ico +0 -0
  333. wx/demo/agw/bitmaps/ffwd.png +0 -0
  334. wx/demo/agw/bitmaps/ffwddisabled.png +0 -0
  335. wx/demo/agw/bitmaps/field-16.png +0 -0
  336. wx/demo/agw/bitmaps/filenew.png +0 -0
  337. wx/demo/agw/bitmaps/fileopen.png +0 -0
  338. wx/demo/agw/bitmaps/filesave.png +0 -0
  339. wx/demo/agw/bitmaps/flagged.ico +0 -0
  340. wx/demo/agw/bitmaps/folder.png +0 -0
  341. wx/demo/agw/bitmaps/folder_new.png +0 -0
  342. wx/demo/agw/bitmaps/ghost.png +0 -0
  343. wx/demo/agw/bitmaps/gradientbutton.png +0 -0
  344. wx/demo/agw/bitmaps/help-16.png +0 -0
  345. wx/demo/agw/bitmaps/help.ico +0 -0
  346. wx/demo/agw/bitmaps/italy.gif +0 -0
  347. wx/demo/agw/bitmaps/lbadd.png +0 -0
  348. wx/demo/agw/bitmaps/lbcharge.png +0 -0
  349. wx/demo/agw/bitmaps/lbdecrypted.png +0 -0
  350. wx/demo/agw/bitmaps/lbnews.png +0 -0
  351. wx/demo/agw/bitmaps/lbroll.png +0 -0
  352. wx/demo/agw/bitmaps/minus1.ico +0 -0
  353. wx/demo/agw/bitmaps/minus2.ico +0 -0
  354. wx/demo/agw/bitmaps/minus3.ico +0 -0
  355. wx/demo/agw/bitmaps/minus4.ico +0 -0
  356. wx/demo/agw/bitmaps/minus5.ico +0 -0
  357. wx/demo/agw/bitmaps/month-16.png +0 -0
  358. wx/demo/agw/bitmaps/new_file.png +0 -0
  359. wx/demo/agw/bitmaps/new_folder.png +0 -0
  360. wx/demo/agw/bitmaps/notchecked.ico +0 -0
  361. wx/demo/agw/bitmaps/notflagged.ico +0 -0
  362. wx/demo/agw/bitmaps/ok-16.png +0 -0
  363. wx/demo/agw/bitmaps/open_folder.png +0 -0
  364. wx/demo/agw/bitmaps/paste.png +0 -0
  365. wx/demo/agw/bitmaps/pause.png +0 -0
  366. wx/demo/agw/bitmaps/pausedisabled.png +0 -0
  367. wx/demo/agw/bitmaps/play.png +0 -0
  368. wx/demo/agw/bitmaps/playdisabled.png +0 -0
  369. wx/demo/agw/bitmaps/plus1.ico +0 -0
  370. wx/demo/agw/bitmaps/plus2.ico +0 -0
  371. wx/demo/agw/bitmaps/plus3.ico +0 -0
  372. wx/demo/agw/bitmaps/plus4.ico +0 -0
  373. wx/demo/agw/bitmaps/plus5.ico +0 -0
  374. wx/demo/agw/bitmaps/record.png +0 -0
  375. wx/demo/agw/bitmaps/recorddisabled.png +0 -0
  376. wx/demo/agw/bitmaps/recording.gif +0 -0
  377. wx/demo/agw/bitmaps/rewind.png +0 -0
  378. wx/demo/agw/bitmaps/rewinddisabled.png +0 -0
  379. wx/demo/agw/bitmaps/round.png +0 -0
  380. wx/demo/agw/bitmaps/save.png +0 -0
  381. wx/demo/agw/bitmaps/separator.gif +0 -0
  382. wx/demo/agw/bitmaps/separatorflip.png +0 -0
  383. wx/demo/agw/bitmaps/smfuel.ico +0 -0
  384. wx/demo/agw/bitmaps/smpi.ico +0 -0
  385. wx/demo/agw/bitmaps/smtemp.ico +0 -0
  386. wx/demo/agw/bitmaps/stop.png +0 -0
  387. wx/demo/agw/bitmaps/stopdisabled.png +0 -0
  388. wx/demo/agw/bitmaps/sttbutton.png +0 -0
  389. wx/demo/agw/bitmaps/sttfont.png +0 -0
  390. wx/demo/agw/bitmaps/sttheader.png +0 -0
  391. wx/demo/agw/bitmaps/stthelp.png +0 -0
  392. wx/demo/agw/bitmaps/view1.png +0 -0
  393. wx/demo/agw/bitmaps/view2.png +0 -0
  394. wx/demo/agw/bitmaps/view_choose.png +0 -0
  395. wx/demo/agw/bitmaps/view_detailed.png +0 -0
  396. wx/demo/agw/bitmaps/view_icon.png +0 -0
  397. wx/demo/agw/bitmaps/view_multicolumn.png +0 -0
  398. wx/demo/agw/bitmaps/viewmag-16.png +0 -0
  399. wx/demo/agw/bitmaps/viewmag-m-16.png +0 -0
  400. wx/demo/agw/bitmaps/viewmag-p-16.png +0 -0
  401. wx/demo/agw/bitmaps/viewmagfit-16.png +0 -0
  402. wx/demo/agw/data/Example_1.xls +0 -0
  403. wx/demo/agw/images.py +6714 -0
  404. wx/demo/bitmaps/AG00028_.gif +0 -0
  405. wx/demo/bitmaps/AG00039_.gif +0 -0
  406. wx/demo/bitmaps/AG00178_.gif +0 -0
  407. wx/demo/bitmaps/AG00183_.gif +0 -0
  408. wx/demo/bitmaps/AG00185_.gif +0 -0
  409. wx/demo/bitmaps/BD13656_.gif +0 -0
  410. wx/demo/bitmaps/advancedsplash.png +0 -0
  411. wx/demo/bitmaps/aquabutton.png +0 -0
  412. wx/demo/bitmaps/aquachecked.ico +0 -0
  413. wx/demo/bitmaps/aquaflagged.ico +0 -0
  414. wx/demo/bitmaps/aquanotchecked.ico +0 -0
  415. wx/demo/bitmaps/aquanotflagged.ico +0 -0
  416. wx/demo/bitmaps/canada.gif +0 -0
  417. wx/demo/bitmaps/checked.ico +0 -0
  418. wx/demo/bitmaps/columns.png +0 -0
  419. wx/demo/bitmaps/contexthelp-16.png +0 -0
  420. wx/demo/bitmaps/contexthelp.png +0 -0
  421. wx/demo/bitmaps/copy.png +0 -0
  422. wx/demo/bitmaps/cropshot24x20.png +0 -0
  423. wx/demo/bitmaps/cut.png +0 -0
  424. wx/demo/bitmaps/editcopy.png +0 -0
  425. wx/demo/bitmaps/editcut.png +0 -0
  426. wx/demo/bitmaps/editpaste.png +0 -0
  427. wx/demo/bitmaps/exit-16.png +0 -0
  428. wx/demo/bitmaps/exit.ico +0 -0
  429. wx/demo/bitmaps/ffwd.png +0 -0
  430. wx/demo/bitmaps/ffwddisabled.png +0 -0
  431. wx/demo/bitmaps/field-16.png +0 -0
  432. wx/demo/bitmaps/filenew.png +0 -0
  433. wx/demo/bitmaps/fileopen.png +0 -0
  434. wx/demo/bitmaps/filesave.png +0 -0
  435. wx/demo/bitmaps/flagged.ico +0 -0
  436. wx/demo/bitmaps/folder_new.png +0 -0
  437. wx/demo/bitmaps/ghost.png +0 -0
  438. wx/demo/bitmaps/gradientbutton.png +0 -0
  439. wx/demo/bitmaps/help-16.png +0 -0
  440. wx/demo/bitmaps/help.ico +0 -0
  441. wx/demo/bitmaps/honeycomb300.png +0 -0
  442. wx/demo/bitmaps/image.bmp +0 -0
  443. wx/demo/bitmaps/image.gif +0 -0
  444. wx/demo/bitmaps/image.ico +0 -0
  445. wx/demo/bitmaps/image.jpg +0 -0
  446. wx/demo/bitmaps/image.png +0 -0
  447. wx/demo/bitmaps/image.tif +0 -0
  448. wx/demo/bitmaps/italy.gif +0 -0
  449. wx/demo/bitmaps/lbadd.png +0 -0
  450. wx/demo/bitmaps/lbcharge.png +0 -0
  451. wx/demo/bitmaps/lbdecrypted.png +0 -0
  452. wx/demo/bitmaps/lbnews.png +0 -0
  453. wx/demo/bitmaps/lbroll.png +0 -0
  454. wx/demo/bitmaps/minus1.ico +0 -0
  455. wx/demo/bitmaps/minus2.ico +0 -0
  456. wx/demo/bitmaps/minus3.ico +0 -0
  457. wx/demo/bitmaps/minus4.ico +0 -0
  458. wx/demo/bitmaps/minus5.ico +0 -0
  459. wx/demo/bitmaps/month-16.png +0 -0
  460. wx/demo/bitmaps/new_file.png +0 -0
  461. wx/demo/bitmaps/new_folder.png +0 -0
  462. wx/demo/bitmaps/notchecked.ico +0 -0
  463. wx/demo/bitmaps/notflagged.ico +0 -0
  464. wx/demo/bitmaps/ok-16.png +0 -0
  465. wx/demo/bitmaps/open_folder.png +0 -0
  466. wx/demo/bitmaps/paste.png +0 -0
  467. wx/demo/bitmaps/pause.png +0 -0
  468. wx/demo/bitmaps/pausedisabled.png +0 -0
  469. wx/demo/bitmaps/phoenix_title.png +0 -0
  470. wx/demo/bitmaps/phoenix_top.png +0 -0
  471. wx/demo/bitmaps/play.png +0 -0
  472. wx/demo/bitmaps/playdisabled.png +0 -0
  473. wx/demo/bitmaps/plus1.ico +0 -0
  474. wx/demo/bitmaps/plus2.ico +0 -0
  475. wx/demo/bitmaps/plus3.ico +0 -0
  476. wx/demo/bitmaps/plus4.ico +0 -0
  477. wx/demo/bitmaps/plus5.ico +0 -0
  478. wx/demo/bitmaps/record.png +0 -0
  479. wx/demo/bitmaps/recorddisabled.png +0 -0
  480. wx/demo/bitmaps/rewind.png +0 -0
  481. wx/demo/bitmaps/rewinddisabled.png +0 -0
  482. wx/demo/bitmaps/round.png +0 -0
  483. wx/demo/bitmaps/save.png +0 -0
  484. wx/demo/bitmaps/smfuel.ico +0 -0
  485. wx/demo/bitmaps/smpi.ico +0 -0
  486. wx/demo/bitmaps/smtemp.ico +0 -0
  487. wx/demo/bitmaps/snakey_render.png +0 -0
  488. wx/demo/bitmaps/splash.png +0 -0
  489. wx/demo/bitmaps/stop.png +0 -0
  490. wx/demo/bitmaps/stopdisabled.png +0 -0
  491. wx/demo/bitmaps/sttbutton.png +0 -0
  492. wx/demo/bitmaps/sttfont.png +0 -0
  493. wx/demo/bitmaps/sttheader.png +0 -0
  494. wx/demo/bitmaps/stthelp.png +0 -0
  495. wx/demo/bitmaps/toucan.png +0 -0
  496. wx/demo/bitmaps/view1.png +0 -0
  497. wx/demo/bitmaps/view2.png +0 -0
  498. wx/demo/bitmaps/view_choose.png +0 -0
  499. wx/demo/bitmaps/view_detailed.png +0 -0
  500. wx/demo/bitmaps/view_icon.png +0 -0
  501. wx/demo/bitmaps/view_multicolumn.png +0 -0
  502. wx/demo/bitmaps/viewmag-16.png +0 -0
  503. wx/demo/bitmaps/viewmag-m-16.png +0 -0
  504. wx/demo/bitmaps/viewmag-p-16.png +0 -0
  505. wx/demo/bitmaps/viewmagfit-16.png +0 -0
  506. wx/demo/bmp_source/001.png +0 -0
  507. wx/demo/bmp_source/002.png +0 -0
  508. wx/demo/bmp_source/003.png +0 -0
  509. wx/demo/bmp_source/004.png +0 -0
  510. wx/demo/bmp_source/005.png +0 -0
  511. wx/demo/bmp_source/006.png +0 -0
  512. wx/demo/bmp_source/007.png +0 -0
  513. wx/demo/bmp_source/008.png +0 -0
  514. wx/demo/bmp_source/009.png +0 -0
  515. wx/demo/bmp_source/010.png +0 -0
  516. wx/demo/bmp_source/011.png +0 -0
  517. wx/demo/bmp_source/012.png +0 -0
  518. wx/demo/bmp_source/013.png +0 -0
  519. wx/demo/bmp_source/014.png +0 -0
  520. wx/demo/bmp_source/015.png +0 -0
  521. wx/demo/bmp_source/016.png +0 -0
  522. wx/demo/bmp_source/017.png +0 -0
  523. wx/demo/bmp_source/018.png +0 -0
  524. wx/demo/bmp_source/019.png +0 -0
  525. wx/demo/bmp_source/020.png +0 -0
  526. wx/demo/bmp_source/021.png +0 -0
  527. wx/demo/bmp_source/022.png +0 -0
  528. wx/demo/bmp_source/023.png +0 -0
  529. wx/demo/bmp_source/024.png +0 -0
  530. wx/demo/bmp_source/025.png +0 -0
  531. wx/demo/bmp_source/026.png +0 -0
  532. wx/demo/bmp_source/027.png +0 -0
  533. wx/demo/bmp_source/028.png +0 -0
  534. wx/demo/bmp_source/029.png +0 -0
  535. wx/demo/bmp_source/030.png +0 -0
  536. wx/demo/bmp_source/DbDec.bmp +0 -0
  537. wx/demo/bmp_source/DbInc.bmp +0 -0
  538. wx/demo/bmp_source/Dec.bmp +0 -0
  539. wx/demo/bmp_source/FRM_0.png +0 -0
  540. wx/demo/bmp_source/FRM_1.png +0 -0
  541. wx/demo/bmp_source/FRM_2.png +0 -0
  542. wx/demo/bmp_source/FRM_3.png +0 -0
  543. wx/demo/bmp_source/FRM_4.png +0 -0
  544. wx/demo/bmp_source/FRM_5.png +0 -0
  545. wx/demo/bmp_source/FRM_6.png +0 -0
  546. wx/demo/bmp_source/FRM_7.png +0 -0
  547. wx/demo/bmp_source/FRM_8.png +0 -0
  548. wx/demo/bmp_source/GridBG.gif +0 -0
  549. wx/demo/bmp_source/Inc.bmp +0 -0
  550. wx/demo/bmp_source/LB01.png +0 -0
  551. wx/demo/bmp_source/LB02.png +0 -0
  552. wx/demo/bmp_source/LB03.png +0 -0
  553. wx/demo/bmp_source/LB04.png +0 -0
  554. wx/demo/bmp_source/LB05.png +0 -0
  555. wx/demo/bmp_source/LB06.png +0 -0
  556. wx/demo/bmp_source/LB07.png +0 -0
  557. wx/demo/bmp_source/LB08.png +0 -0
  558. wx/demo/bmp_source/LB09.png +0 -0
  559. wx/demo/bmp_source/LB10.png +0 -0
  560. wx/demo/bmp_source/LB11.png +0 -0
  561. wx/demo/bmp_source/LB12.png +0 -0
  562. wx/demo/bmp_source/Pt.bmp +0 -0
  563. wx/demo/bmp_source/Vippi.png +0 -0
  564. wx/demo/bmp_source/backgrnd.png +0 -0
  565. wx/demo/bmp_source/book.png +0 -0
  566. wx/demo/bmp_source/book_blue.png +0 -0
  567. wx/demo/bmp_source/book_green.png +0 -0
  568. wx/demo/bmp_source/book_red.png +0 -0
  569. wx/demo/bmp_source/bp_btn1.png +0 -0
  570. wx/demo/bmp_source/bp_btn2.png +0 -0
  571. wx/demo/bmp_source/bp_btn3.png +0 -0
  572. wx/demo/bmp_source/bp_btn4.png +0 -0
  573. wx/demo/bmp_source/bulb1.bmp +0 -0
  574. wx/demo/bmp_source/bulb2.bmp +0 -0
  575. wx/demo/bmp_source/carrot.png +0 -0
  576. wx/demo/bmp_source/clipboard.png +0 -0
  577. wx/demo/bmp_source/code.png +0 -0
  578. wx/demo/bmp_source/core.png +0 -0
  579. wx/demo/bmp_source/custom.png +0 -0
  580. wx/demo/bmp_source/customcontrol.png +0 -0
  581. wx/demo/bmp_source/deletedocs.png +0 -0
  582. wx/demo/bmp_source/deleteperspective.png +0 -0
  583. wx/demo/bmp_source/demo.png +0 -0
  584. wx/demo/bmp_source/dialog.png +0 -0
  585. wx/demo/bmp_source/exit.png +0 -0
  586. wx/demo/bmp_source/expansion.png +0 -0
  587. wx/demo/bmp_source/find.png +0 -0
  588. wx/demo/bmp_source/findnext.png +0 -0
  589. wx/demo/bmp_source/floatcanvas.png +0 -0
  590. wx/demo/bmp_source/frame.png +0 -0
  591. wx/demo/bmp_source/images.png +0 -0
  592. wx/demo/bmp_source/inspect.png +0 -0
  593. wx/demo/bmp_source/layout.png +0 -0
  594. wx/demo/bmp_source/logo.png +0 -0
  595. wx/demo/bmp_source/miscellaneous.png +0 -0
  596. wx/demo/bmp_source/modifiedexists.png +0 -0
  597. wx/demo/bmp_source/mondrian.ico +0 -0
  598. wx/demo/bmp_source/morecontrols.png +0 -0
  599. wx/demo/bmp_source/moredialog.png +0 -0
  600. wx/demo/bmp_source/noicon.png +0 -0
  601. wx/demo/bmp_source/overview.png +0 -0
  602. wx/demo/bmp_source/pencil.png +0 -0
  603. wx/demo/bmp_source/pointy.png +0 -0
  604. wx/demo/bmp_source/process.png +0 -0
  605. wx/demo/bmp_source/pyshell.png +0 -0
  606. wx/demo/bmp_source/recent.png +0 -0
  607. wx/demo/bmp_source/rest.png +0 -0
  608. wx/demo/bmp_source/robin.jpg +0 -0
  609. wx/demo/bmp_source/rt_alignleft.xpm +24 -0
  610. wx/demo/bmp_source/rt_alignright.xpm +24 -0
  611. wx/demo/bmp_source/rt_bold.xpm +24 -0
  612. wx/demo/bmp_source/rt_centre.xpm +24 -0
  613. wx/demo/bmp_source/rt_colour.xpm +59 -0
  614. wx/demo/bmp_source/rt_copy.xpm +44 -0
  615. wx/demo/bmp_source/rt_cut.xpm +46 -0
  616. wx/demo/bmp_source/rt_font.xpm +25 -0
  617. wx/demo/bmp_source/rt_idea.xpm +47 -0
  618. wx/demo/bmp_source/rt_indentless.xpm +25 -0
  619. wx/demo/bmp_source/rt_indentmore.xpm +25 -0
  620. wx/demo/bmp_source/rt_italic.xpm +25 -0
  621. wx/demo/bmp_source/rt_open.xpm +57 -0
  622. wx/demo/bmp_source/rt_paste.xpm +46 -0
  623. wx/demo/bmp_source/rt_redo.xpm +58 -0
  624. wx/demo/bmp_source/rt_sample.xpm +44 -0
  625. wx/demo/bmp_source/rt_save.xpm +42 -0
  626. wx/demo/bmp_source/rt_smiley.xpm +42 -0
  627. wx/demo/bmp_source/rt_underline.xpm +25 -0
  628. wx/demo/bmp_source/rt_undo.xpm +58 -0
  629. wx/demo/bmp_source/rt_zebra.xpm +409 -0
  630. wx/demo/bmp_source/saveperspective.png +0 -0
  631. wx/demo/bmp_source/sm_down.bmp +0 -0
  632. wx/demo/bmp_source/sm_up.bmp +0 -0
  633. wx/demo/bmp_source/smiles2.bmp +0 -0
  634. wx/demo/bmp_source/test2.bmp +0 -0
  635. wx/demo/bmp_source/testmask.bmp +0 -0
  636. wx/demo/bmp_source/teststar.png +0 -0
  637. wx/demo/bmp_source/thekid.png +0 -0
  638. wx/demo/bmp_source/tog1.bmp +0 -0
  639. wx/demo/bmp_source/tog2.bmp +0 -0
  640. wx/demo/bmp_source/wiztest1.bmp +0 -0
  641. wx/demo/bmp_source/wiztest2.bmp +0 -0
  642. wx/demo/bmp_source/wxpdemo.ico +0 -0
  643. wx/demo/cursors/paperairplane_arrow_blue.cur +0 -0
  644. wx/demo/cursors/paperairplane_arrow_blue_fadeout80.cur +0 -0
  645. wx/demo/cursors/paperairplane_arrow_colorshift.ani +0 -0
  646. wx/demo/cursors/paperairplane_arrow_dark.cur +0 -0
  647. wx/demo/cursors/paperairplane_arrow_grey.cur +0 -0
  648. wx/demo/cursors/paperairplane_arrow_red.cur +0 -0
  649. wx/demo/cursors/paperairplane_arrow_white.cur +0 -0
  650. wx/demo/cursors/paperairplane_arrow_white24.png +0 -0
  651. wx/demo/data/0-tiger.svg +725 -0
  652. wx/demo/data/Asteroid_blaster.swf +0 -0
  653. wx/demo/data/SIL_OPEN_FONT_LICENSE.txt +97 -0
  654. wx/demo/data/SourceCodePro-Regular.ttf +0 -0
  655. wx/demo/data/accessories-calculator.svg +636 -0
  656. wx/demo/data/accessories-text-editor.svg +554 -0
  657. wx/demo/data/anykey.wav +0 -0
  658. wx/demo/data/applications-internet.svg +623 -0
  659. wx/demo/data/desktop-accessibility.svg +245 -0
  660. wx/demo/data/desktop-keyboard-shortcuts.svg +839 -0
  661. wx/demo/data/desktop-locale.svg +878 -0
  662. wx/demo/data/desktop-remote-desktop.svg +1479 -0
  663. wx/demo/data/desktop-theme.svg +882 -0
  664. wx/demo/data/desktop-wallpaper.svg +747 -0
  665. wx/demo/data/echo.py +25 -0
  666. wx/demo/data/imagemap.htm +20 -0
  667. wx/demo/data/imagemap.png +0 -0
  668. wx/demo/data/internet-group-chat.svg +312 -0
  669. wx/demo/data/internet-mail.svg +440 -0
  670. wx/demo/data/locale/af/LC_MESSAGES/wxpydemo.mo +0 -0
  671. wx/demo/data/locale/de/LC_MESSAGES/wxpydemo.mo +0 -0
  672. wx/demo/data/locale/es/LC_MESSAGES/wxpydemo.mo +0 -0
  673. wx/demo/data/locale/fr/LC_MESSAGES/wxpydemo.mo +0 -0
  674. wx/demo/data/locale/it/LC_MESSAGES/wxpydemo.mo +0 -0
  675. wx/demo/data/locale-src/af.po +23 -0
  676. wx/demo/data/locale-src/de.po +23 -0
  677. wx/demo/data/locale-src/es.po +22 -0
  678. wx/demo/data/locale-src/fr.po +22 -0
  679. wx/demo/data/locale-src/install +15 -0
  680. wx/demo/data/locale-src/it.po +23 -0
  681. wx/demo/data/locale-src/wxpydemo.po +21 -0
  682. wx/demo/data/office-calendar.svg +316 -0
  683. wx/demo/data/pic.png +0 -0
  684. wx/demo/data/pic2.bmp +0 -0
  685. wx/demo/data/plan.wav +0 -0
  686. wx/demo/data/proclamation.txt +115 -0
  687. wx/demo/data/resource.wdr +0 -0
  688. wx/demo/data/resource_wdr.xrc +146 -0
  689. wx/demo/data/romedalen.png +0 -0
  690. wx/demo/data/stc.h.html +3544 -0
  691. wx/demo/data/system-session.svg +510 -0
  692. wx/demo/data/system-users.svg +539 -0
  693. wx/demo/data/tables.htm +116 -0
  694. wx/demo/data/test-gradient-pen.svg +14 -0
  695. wx/demo/data/test-opacity.svg +7 -0
  696. wx/demo/data/test.htm +253 -0
  697. wx/demo/data/testmovie.mpg +0 -0
  698. wx/demo/data/testtable.txt +38 -0
  699. wx/demo/data/tips.txt +73 -0
  700. wx/demo/data/utilities-system-monitor.svg +435 -0
  701. wx/demo/data/utilities-terminal.svg +500 -0
  702. wx/demo/data/widgetTest.htm +70 -0
  703. wx/demo/data/world.dat +24055 -0
  704. wx/demo/demo.py +4 -0
  705. wx/demo/demo.pyw +4 -0
  706. wx/demo/demodata.py +310 -0
  707. wx/demo/encode_bitmaps.py +181 -0
  708. wx/demo/images.py +6812 -0
  709. wx/demo/infoframe.py +149 -0
  710. wx/demo/run.py +171 -0
  711. wx/demo/snippets/__init__.py +13 -0
  712. wx/demo/snippets/arc.py +21 -0
  713. wx/demo/snippets/arc_negative.py +21 -0
  714. wx/demo/snippets/clip.py +13 -0
  715. wx/demo/snippets/clip_image.py +13 -0
  716. wx/demo/snippets/curve_rectangle.py +53 -0
  717. wx/demo/snippets/curve_to.py +17 -0
  718. wx/demo/snippets/dash.py +18 -0
  719. wx/demo/snippets/ellipse.py +33 -0
  720. wx/demo/snippets/fill_and_stroke.py +12 -0
  721. wx/demo/snippets/fill_and_stroke2.py +18 -0
  722. wx/demo/snippets/fill_style.py +31 -0
  723. wx/demo/snippets/glyph_path.py +21 -0
  724. wx/demo/snippets/gradient.py +16 -0
  725. wx/demo/snippets/gradient_mask.py +12 -0
  726. wx/demo/snippets/group.py +16 -0
  727. wx/demo/snippets/image.py +14 -0
  728. wx/demo/snippets/imagepattern.py +23 -0
  729. wx/demo/snippets/path.py +7 -0
  730. wx/demo/snippets/set_line_cap.py +19 -0
  731. wx/demo/snippets/set_line_join.py +21 -0
  732. wx/demo/snippets/show_glyphs.py +15 -0
  733. wx/demo/snippets/text.py +22 -0
  734. wx/demo/snippets/text_align_center.py +26 -0
  735. wx/demo/snippets/text_extents.py +27 -0
  736. wx/demo/template.py +36 -0
  737. wx/demo/throbImages.py +1277 -0
  738. wx/demo/version.py +3 -0
  739. wx/demo/widgetTest.py +72 -0
  740. wx/demo/wxpdemo.ico +0 -0
  741. wx/glcanvas.py +10 -0
  742. wx/glcanvas.pyi +458 -0
  743. wx/grid.py +229 -0
  744. wx/grid.pyi +4959 -0
  745. wx/html.py +35 -0
  746. wx/html.pyi +2965 -0
  747. wx/html2.py +40 -0
  748. wx/html2.pyi +772 -0
  749. wx/lib/CDate.py +202 -0
  750. wx/lib/ClickableHtmlWindow.py +57 -0
  751. wx/lib/__init__.py +0 -0
  752. wx/lib/activex.py +178 -0
  753. wx/lib/activexwrapper.py +153 -0
  754. wx/lib/agw/__init__.py +128 -0
  755. wx/lib/agw/advancedsplash.py +564 -0
  756. wx/lib/agw/aquabutton.py +1127 -0
  757. wx/lib/agw/artmanager.py +2110 -0
  758. wx/lib/agw/aui/__init__.py +295 -0
  759. wx/lib/agw/aui/aui_constants.py +2628 -0
  760. wx/lib/agw/aui/aui_switcherdialog.py +1227 -0
  761. wx/lib/agw/aui/aui_utilities.py +672 -0
  762. wx/lib/agw/aui/auibar.py +4031 -0
  763. wx/lib/agw/aui/auibook.py +6289 -0
  764. wx/lib/agw/aui/dockart.py +1198 -0
  765. wx/lib/agw/aui/framemanager.py +10409 -0
  766. wx/lib/agw/aui/tabart.py +2771 -0
  767. wx/lib/agw/aui/tabmdi.py +679 -0
  768. wx/lib/agw/balloontip.py +1158 -0
  769. wx/lib/agw/buttonpanel.py +2823 -0
  770. wx/lib/agw/cubecolourdialog.py +3529 -0
  771. wx/lib/agw/customtreectrl.py +8963 -0
  772. wx/lib/agw/data/ShortcutEditor_1.png +0 -0
  773. wx/lib/agw/data/ShortcutEditor_1_thumb.png +0 -0
  774. wx/lib/agw/data/ShortcutEditor_2.png +0 -0
  775. wx/lib/agw/data/ShortcutEditor_2_thumb.png +0 -0
  776. wx/lib/agw/data/ShortcutEditor_3.png +0 -0
  777. wx/lib/agw/data/ShortcutEditor_3_thumb.png +0 -0
  778. wx/lib/agw/data/ShortcutEditor_4.png +0 -0
  779. wx/lib/agw/data/ShortcutEditor_4_thumb.png +0 -0
  780. wx/lib/agw/data/default_help_text.html +105 -0
  781. wx/lib/agw/flatmenu.py +7333 -0
  782. wx/lib/agw/flatnotebook.py +6672 -0
  783. wx/lib/agw/floatspin.py +1823 -0
  784. wx/lib/agw/fmcustomizedlg.py +540 -0
  785. wx/lib/agw/fmresources.py +407 -0
  786. wx/lib/agw/foldpanelbar.py +2282 -0
  787. wx/lib/agw/fourwaysplitter.py +1130 -0
  788. wx/lib/agw/genericmessagedialog.py +1549 -0
  789. wx/lib/agw/gradientbutton.py +732 -0
  790. wx/lib/agw/hyperlink.py +664 -0
  791. wx/lib/agw/hypertreelist.py +5374 -0
  792. wx/lib/agw/infobar.py +885 -0
  793. wx/lib/agw/knobctrl.py +945 -0
  794. wx/lib/agw/labelbook.py +3029 -0
  795. wx/lib/agw/multidirdialog.py +615 -0
  796. wx/lib/agw/peakmeter.py +1029 -0
  797. wx/lib/agw/persist/__init__.py +188 -0
  798. wx/lib/agw/persist/persist_constants.py +284 -0
  799. wx/lib/agw/persist/persist_handlers.py +2614 -0
  800. wx/lib/agw/persist/persistencemanager.py +864 -0
  801. wx/lib/agw/piectrl.py +1082 -0
  802. wx/lib/agw/pybusyinfo.py +399 -0
  803. wx/lib/agw/pycollapsiblepane.py +940 -0
  804. wx/lib/agw/pygauge.py +570 -0
  805. wx/lib/agw/pyprogress.py +917 -0
  806. wx/lib/agw/ribbon/__init__.py +198 -0
  807. wx/lib/agw/ribbon/art.py +219 -0
  808. wx/lib/agw/ribbon/art_aui.py +1284 -0
  809. wx/lib/agw/ribbon/art_default.py +81 -0
  810. wx/lib/agw/ribbon/art_internal.py +244 -0
  811. wx/lib/agw/ribbon/art_msw.py +2736 -0
  812. wx/lib/agw/ribbon/art_osx.py +52 -0
  813. wx/lib/agw/ribbon/bar.py +1261 -0
  814. wx/lib/agw/ribbon/buttonbar.py +1320 -0
  815. wx/lib/agw/ribbon/control.py +205 -0
  816. wx/lib/agw/ribbon/gallery.py +974 -0
  817. wx/lib/agw/ribbon/page.py +946 -0
  818. wx/lib/agw/ribbon/panel.py +1170 -0
  819. wx/lib/agw/ribbon/toolbar.py +1442 -0
  820. wx/lib/agw/rulerctrl.py +1887 -0
  821. wx/lib/agw/scrolledthumbnail.py +2119 -0
  822. wx/lib/agw/shapedbutton.py +1809 -0
  823. wx/lib/agw/shortcuteditor.py +2634 -0
  824. wx/lib/agw/speedmeter.py +1801 -0
  825. wx/lib/agw/supertooltip.py +1444 -0
  826. wx/lib/agw/thumbnailctrl.py +529 -0
  827. wx/lib/agw/toasterbox.py +1327 -0
  828. wx/lib/agw/ultimatelistctrl.py +13666 -0
  829. wx/lib/agw/xlsgrid.py +2113 -0
  830. wx/lib/agw/zoombar.py +1339 -0
  831. wx/lib/analogclock/__init__.py +140 -0
  832. wx/lib/analogclock/analogclock.py +631 -0
  833. wx/lib/analogclock/helpers.py +991 -0
  834. wx/lib/analogclock/lib_setup/__init__.py +0 -0
  835. wx/lib/analogclock/lib_setup/buttontreectrlpanel.py +297 -0
  836. wx/lib/analogclock/lib_setup/fontselect.py +57 -0
  837. wx/lib/analogclock/setup.py +490 -0
  838. wx/lib/analogclock/styles.py +47 -0
  839. wx/lib/anchors.py +103 -0
  840. wx/lib/art/__init__.py +4 -0
  841. wx/lib/art/flagart.py +1583 -0
  842. wx/lib/art/img2pyartprov.py +56 -0
  843. wx/lib/busy.py +146 -0
  844. wx/lib/buttons.py +1141 -0
  845. wx/lib/calendar.py +1597 -0
  846. wx/lib/checkbox.py +837 -0
  847. wx/lib/colourchooser/__init__.py +38 -0
  848. wx/lib/colourchooser/canvas.py +145 -0
  849. wx/lib/colourchooser/intl.py +24 -0
  850. wx/lib/colourchooser/pycolourbox.py +89 -0
  851. wx/lib/colourchooser/pycolourchooser.py +629 -0
  852. wx/lib/colourchooser/pycolourslider.py +100 -0
  853. wx/lib/colourchooser/pypalette.py +211 -0
  854. wx/lib/colourdb.py +740 -0
  855. wx/lib/colourselect.py +385 -0
  856. wx/lib/colourutils.py +118 -0
  857. wx/lib/combotreebox.py +944 -0
  858. wx/lib/delayedresult.py +420 -0
  859. wx/lib/dialogs.py +510 -0
  860. wx/lib/docview.py +3210 -0
  861. wx/lib/dragscroller.py +79 -0
  862. wx/lib/editor/README.txt +77 -0
  863. wx/lib/editor/__init__.py +24 -0
  864. wx/lib/editor/editor.py +974 -0
  865. wx/lib/editor/images.py +15 -0
  866. wx/lib/editor/selection.py +44 -0
  867. wx/lib/embeddedimage.py +76 -0
  868. wx/lib/eventStack.py +136 -0
  869. wx/lib/eventwatcher.py +440 -0
  870. wx/lib/evtmgr.py +521 -0
  871. wx/lib/expando.py +393 -0
  872. wx/lib/fancytext.py +505 -0
  873. wx/lib/filebrowsebutton.py +459 -0
  874. wx/lib/flashwin.py +262 -0
  875. wx/lib/flashwin_old.py +651 -0
  876. wx/lib/floatcanvas/FCEvents.py +53 -0
  877. wx/lib/floatcanvas/FCObjects.py +2923 -0
  878. wx/lib/floatcanvas/FloatCanvas.py +1027 -0
  879. wx/lib/floatcanvas/GUIMode.py +396 -0
  880. wx/lib/floatcanvas/NavCanvas.py +161 -0
  881. wx/lib/floatcanvas/Resources.py +319 -0
  882. wx/lib/floatcanvas/ScreenShot.py +1788 -0
  883. wx/lib/floatcanvas/Utilities/BBox.py +314 -0
  884. wx/lib/floatcanvas/Utilities/Colors.py +137 -0
  885. wx/lib/floatcanvas/Utilities/GUI.py +91 -0
  886. wx/lib/floatcanvas/Utilities/__init__.py +7 -0
  887. wx/lib/floatcanvas/__init__.py +124 -0
  888. wx/lib/foldmenu.py +89 -0
  889. wx/lib/gestures.py +310 -0
  890. wx/lib/gizmos/__init__.py +18 -0
  891. wx/lib/gizmos/dynamicsash.py +1202 -0
  892. wx/lib/gizmos/ledctrl.py +300 -0
  893. wx/lib/gizmos/treelistctrl.py +87 -0
  894. wx/lib/graphics.py +1939 -0
  895. wx/lib/gridmovers.py +511 -0
  896. wx/lib/iewin.py +249 -0
  897. wx/lib/iewin_old.py +894 -0
  898. wx/lib/imagebrowser.py +856 -0
  899. wx/lib/imageutils.py +163 -0
  900. wx/lib/infoframe.py +490 -0
  901. wx/lib/inspection.py +1255 -0
  902. wx/lib/intctrl.py +1001 -0
  903. wx/lib/itemspicker.py +256 -0
  904. wx/lib/langlistctrl.py +480 -0
  905. wx/lib/layoutf.py +271 -0
  906. wx/lib/masked/__init__.py +27 -0
  907. wx/lib/masked/combobox.py +839 -0
  908. wx/lib/masked/ctrl.py +108 -0
  909. wx/lib/masked/ipaddrctrl.py +242 -0
  910. wx/lib/masked/maskededit.py +7279 -0
  911. wx/lib/masked/numctrl.py +2001 -0
  912. wx/lib/masked/textctrl.py +465 -0
  913. wx/lib/masked/timectrl.py +1466 -0
  914. wx/lib/mixins/__init__.py +17 -0
  915. wx/lib/mixins/grid.py +47 -0
  916. wx/lib/mixins/gridlabelrenderer.py +251 -0
  917. wx/lib/mixins/imagelist.py +77 -0
  918. wx/lib/mixins/inspection.py +184 -0
  919. wx/lib/mixins/listctrl.py +894 -0
  920. wx/lib/mixins/rubberband.py +404 -0
  921. wx/lib/mixins/treemixin.py +678 -0
  922. wx/lib/msgpanel.py +95 -0
  923. wx/lib/multisash.py +747 -0
  924. wx/lib/myole4ax.idl +178 -0
  925. wx/lib/myole4ax.tlb +0 -0
  926. wx/lib/newevent.py +229 -0
  927. wx/lib/nvdlg.py +156 -0
  928. wx/lib/ogl/__init__.py +13 -0
  929. wx/lib/ogl/basic.py +3991 -0
  930. wx/lib/ogl/bmpshape.py +87 -0
  931. wx/lib/ogl/canvas.py +467 -0
  932. wx/lib/ogl/composit.py +1577 -0
  933. wx/lib/ogl/diagram.py +230 -0
  934. wx/lib/ogl/divided.py +483 -0
  935. wx/lib/ogl/drawn.py +900 -0
  936. wx/lib/ogl/lines.py +1811 -0
  937. wx/lib/ogl/oglmisc.py +608 -0
  938. wx/lib/pdfviewer/__init__.py +113 -0
  939. wx/lib/pdfviewer/bitmaps/ArrowLeft.png +0 -0
  940. wx/lib/pdfviewer/bitmaps/ArrowRight.png +0 -0
  941. wx/lib/pdfviewer/bitmaps/DirectionH.png +0 -0
  942. wx/lib/pdfviewer/bitmaps/DirectionV.png +0 -0
  943. wx/lib/pdfviewer/bitmaps/PlayerFirst.png +0 -0
  944. wx/lib/pdfviewer/bitmaps/PlayerLast.png +0 -0
  945. wx/lib/pdfviewer/bitmaps/PlayerNext.png +0 -0
  946. wx/lib/pdfviewer/bitmaps/PlayerPrev.png +0 -0
  947. wx/lib/pdfviewer/bitmaps/Printer.png +0 -0
  948. wx/lib/pdfviewer/bitmaps/ReadMe.txt +28 -0
  949. wx/lib/pdfviewer/bitmaps/Save.png +0 -0
  950. wx/lib/pdfviewer/bitmaps/ZoomIn.png +0 -0
  951. wx/lib/pdfviewer/bitmaps/ZoomOut.png +0 -0
  952. wx/lib/pdfviewer/bitmaps/encode_bitmaps.py +37 -0
  953. wx/lib/pdfviewer/buttonpanel.py +279 -0
  954. wx/lib/pdfviewer/images.py +240 -0
  955. wx/lib/pdfviewer/viewer.py +1077 -0
  956. wx/lib/pdfwin.py +295 -0
  957. wx/lib/pdfwin_old.py +789 -0
  958. wx/lib/platebtn.py +789 -0
  959. wx/lib/plot/CHANGELOG.md +150 -0
  960. wx/lib/plot/README.md +16 -0
  961. wx/lib/plot/__init__.py +46 -0
  962. wx/lib/plot/__main__.py +5 -0
  963. wx/lib/plot/examples/__init__.py +0 -0
  964. wx/lib/plot/examples/demo.py +1009 -0
  965. wx/lib/plot/examples/simple_example.py +54 -0
  966. wx/lib/plot/plotcanvas.py +2981 -0
  967. wx/lib/plot/polyobjects.py +1525 -0
  968. wx/lib/plot/utils.py +327 -0
  969. wx/lib/popupctl.py +250 -0
  970. wx/lib/printout.py +1157 -0
  971. wx/lib/progressindicator.py +151 -0
  972. wx/lib/pubsub/LICENSE_BSD_Simple.txt +23 -0
  973. wx/lib/pubsub/README_WxPython.txt +22 -0
  974. wx/lib/pubsub/RELEASE_NOTES.txt +71 -0
  975. wx/lib/pubsub/__init__.py +25 -0
  976. wx/lib/pubsub/core/__init__.py +92 -0
  977. wx/lib/pubsub/core/arg1/__init__.py +16 -0
  978. wx/lib/pubsub/core/arg1/listenerimpl.py +97 -0
  979. wx/lib/pubsub/core/arg1/publisher.py +40 -0
  980. wx/lib/pubsub/core/arg1/publishermixin.py +34 -0
  981. wx/lib/pubsub/core/arg1/topicargspecimpl.py +66 -0
  982. wx/lib/pubsub/core/arg1/topicmgrimpl.py +19 -0
  983. wx/lib/pubsub/core/callables.py +191 -0
  984. wx/lib/pubsub/core/imp2.py +63 -0
  985. wx/lib/pubsub/core/itopicdefnprovider.py +0 -0
  986. wx/lib/pubsub/core/kwargs/__init__.py +16 -0
  987. wx/lib/pubsub/core/kwargs/datamsg.py +27 -0
  988. wx/lib/pubsub/core/kwargs/listenerimpl.py +93 -0
  989. wx/lib/pubsub/core/kwargs/publisher.py +77 -0
  990. wx/lib/pubsub/core/kwargs/publishermixin.py +65 -0
  991. wx/lib/pubsub/core/kwargs/topicargspecimpl.py +217 -0
  992. wx/lib/pubsub/core/kwargs/topicmgrimpl.py +13 -0
  993. wx/lib/pubsub/core/listener.py +40 -0
  994. wx/lib/pubsub/core/listenerbase.py +185 -0
  995. wx/lib/pubsub/core/notificationmgr.py +185 -0
  996. wx/lib/pubsub/core/publisherbase.py +191 -0
  997. wx/lib/pubsub/core/topicargspec.py +77 -0
  998. wx/lib/pubsub/core/topicdefnprovider.py +632 -0
  999. wx/lib/pubsub/core/topicexc.py +72 -0
  1000. wx/lib/pubsub/core/topicmgr.py +456 -0
  1001. wx/lib/pubsub/core/topicobj.py +472 -0
  1002. wx/lib/pubsub/core/topictreetraverser.py +143 -0
  1003. wx/lib/pubsub/core/topicutils.py +118 -0
  1004. wx/lib/pubsub/core/treeconfig.py +21 -0
  1005. wx/lib/pubsub/core/validatedefnargs.py +29 -0
  1006. wx/lib/pubsub/core/weakmethod.py +102 -0
  1007. wx/lib/pubsub/policies.py +24 -0
  1008. wx/lib/pubsub/pub.py +199 -0
  1009. wx/lib/pubsub/py2and3.py +608 -0
  1010. wx/lib/pubsub/setuparg1.py +47 -0
  1011. wx/lib/pubsub/setupkwargs.py +29 -0
  1012. wx/lib/pubsub/utils/__init__.py +27 -0
  1013. wx/lib/pubsub/utils/exchandling.py +100 -0
  1014. wx/lib/pubsub/utils/misc.py +100 -0
  1015. wx/lib/pubsub/utils/notification.py +331 -0
  1016. wx/lib/pubsub/utils/topictreeprinter.py +195 -0
  1017. wx/lib/pubsub/utils/xmltopicdefnprovider.py +287 -0
  1018. wx/lib/pydocview.py +3300 -0
  1019. wx/lib/rcsizer.py +229 -0
  1020. wx/lib/resizewidget.py +357 -0
  1021. wx/lib/scrolledpanel.py +225 -0
  1022. wx/lib/sheet.py +350 -0
  1023. wx/lib/sized_controls.py +691 -0
  1024. wx/lib/softwareupdate.py +361 -0
  1025. wx/lib/splitter.py +925 -0
  1026. wx/lib/statbmp.py +199 -0
  1027. wx/lib/stattext.py +322 -0
  1028. wx/lib/throbber.py +425 -0
  1029. wx/lib/ticker.py +295 -0
  1030. wx/lib/ticker_xrc.py +48 -0
  1031. wx/lib/utils.py +89 -0
  1032. wx/lib/wordwrap.py +97 -0
  1033. wx/lib/wxcairo/__init__.py +124 -0
  1034. wx/lib/wxcairo/wx_cairocffi.py +200 -0
  1035. wx/lib/wxcairo/wx_pycairo.py +463 -0
  1036. wx/lib/wxpTag.py +274 -0
  1037. wx/locale/af/LC_MESSAGES/wxstd.mo +0 -0
  1038. wx/locale/an/LC_MESSAGES/wxstd.mo +0 -0
  1039. wx/locale/ar/LC_MESSAGES/wxstd.mo +0 -0
  1040. wx/locale/ca/LC_MESSAGES/wxstd.mo +0 -0
  1041. wx/locale/ca@valencia/LC_MESSAGES/wxstd.mo +0 -0
  1042. wx/locale/cs/LC_MESSAGES/wxstd.mo +0 -0
  1043. wx/locale/da/LC_MESSAGES/wxstd.mo +0 -0
  1044. wx/locale/de/LC_MESSAGES/wxstd.mo +0 -0
  1045. wx/locale/el/LC_MESSAGES/wxstd.mo +0 -0
  1046. wx/locale/es/LC_MESSAGES/wxstd.mo +0 -0
  1047. wx/locale/eu/LC_MESSAGES/wxstd.mo +0 -0
  1048. wx/locale/fa_IR/LC_MESSAGES/wxstd.mo +0 -0
  1049. wx/locale/fi/LC_MESSAGES/wxstd.mo +0 -0
  1050. wx/locale/fr/LC_MESSAGES/wxstd.mo +0 -0
  1051. wx/locale/gl_ES/LC_MESSAGES/wxstd.mo +0 -0
  1052. wx/locale/hi/LC_MESSAGES/wxstd.mo +0 -0
  1053. wx/locale/hr/LC_MESSAGES/wxstd.mo +0 -0
  1054. wx/locale/hu/LC_MESSAGES/wxstd.mo +0 -0
  1055. wx/locale/id/LC_MESSAGES/wxstd.mo +0 -0
  1056. wx/locale/it/LC_MESSAGES/wxstd.mo +0 -0
  1057. wx/locale/ja/LC_MESSAGES/wxstd.mo +0 -0
  1058. wx/locale/ka/LC_MESSAGES/wxstd.mo +0 -0
  1059. wx/locale/ko_KR/LC_MESSAGES/wxstd.mo +0 -0
  1060. wx/locale/lt/LC_MESSAGES/wxstd.mo +0 -0
  1061. wx/locale/lv/LC_MESSAGES/wxstd.mo +0 -0
  1062. wx/locale/ms/LC_MESSAGES/wxstd.mo +0 -0
  1063. wx/locale/nb/LC_MESSAGES/wxstd.mo +0 -0
  1064. wx/locale/ne/LC_MESSAGES/wxstd.mo +0 -0
  1065. wx/locale/nl/LC_MESSAGES/wxstd.mo +0 -0
  1066. wx/locale/pl/LC_MESSAGES/wxstd.mo +0 -0
  1067. wx/locale/pt/LC_MESSAGES/wxstd.mo +0 -0
  1068. wx/locale/pt_BR/LC_MESSAGES/wxstd.mo +0 -0
  1069. wx/locale/ro/LC_MESSAGES/wxstd.mo +0 -0
  1070. wx/locale/ru/LC_MESSAGES/wxstd.mo +0 -0
  1071. wx/locale/sk/LC_MESSAGES/wxstd.mo +0 -0
  1072. wx/locale/sl/LC_MESSAGES/wxstd.mo +0 -0
  1073. wx/locale/sq/LC_MESSAGES/wxstd.mo +0 -0
  1074. wx/locale/sv/LC_MESSAGES/wxstd.mo +0 -0
  1075. wx/locale/ta/LC_MESSAGES/wxstd.mo +0 -0
  1076. wx/locale/tr/LC_MESSAGES/wxstd.mo +0 -0
  1077. wx/locale/uk/LC_MESSAGES/wxstd.mo +0 -0
  1078. wx/locale/vi/LC_MESSAGES/wxstd.mo +0 -0
  1079. wx/locale/zh_CN/LC_MESSAGES/wxstd.mo +0 -0
  1080. wx/locale/zh_TW/LC_MESSAGES/wxstd.mo +0 -0
  1081. wx/media.py +27 -0
  1082. wx/media.pyi +223 -0
  1083. wx/msw.py +13 -0
  1084. wx/msw.pyi +65 -0
  1085. wx/propgrid.py +1451 -0
  1086. wx/propgrid.pyi +7914 -0
  1087. wx/py/CHANGES.txt +796 -0
  1088. wx/py/Py.ico +0 -0
  1089. wx/py/PyAlaCarte.py +34 -0
  1090. wx/py/PyAlaMode.py +34 -0
  1091. wx/py/PyAlaModeTest.py +33 -0
  1092. wx/py/PyCrust.ico +0 -0
  1093. wx/py/PyCrust.py +78 -0
  1094. wx/py/PyCrust_16.png +0 -0
  1095. wx/py/PyCrust_32.png +0 -0
  1096. wx/py/PyFilling.py +35 -0
  1097. wx/py/PyShell.py +78 -0
  1098. wx/py/PySlices.ico +0 -0
  1099. wx/py/PySlices.py +98 -0
  1100. wx/py/PySlicesShell.py +94 -0
  1101. wx/py/PySlices_16.png +0 -0
  1102. wx/py/PySlices_32.png +0 -0
  1103. wx/py/PyWrap.py +52 -0
  1104. wx/py/README.txt +77 -0
  1105. wx/py/__init__.py +20 -0
  1106. wx/py/buffer.py +136 -0
  1107. wx/py/crust.py +403 -0
  1108. wx/py/crustslices.py +403 -0
  1109. wx/py/dispatcher.py +259 -0
  1110. wx/py/document.py +37 -0
  1111. wx/py/editor.py +844 -0
  1112. wx/py/editwindow.py +299 -0
  1113. wx/py/filling.py +357 -0
  1114. wx/py/frame.py +978 -0
  1115. wx/py/images.py +212 -0
  1116. wx/py/interpreter.py +170 -0
  1117. wx/py/introspect.py +393 -0
  1118. wx/py/magic.py +98 -0
  1119. wx/py/parse.py +134 -0
  1120. wx/py/path.py +36 -0
  1121. wx/py/pseudo.py +99 -0
  1122. wx/py/shell.py +1588 -0
  1123. wx/py/sliceshell.py +3814 -0
  1124. wx/py/tests/test_interpreter.py +71 -0
  1125. wx/py/tests/test_introspect.py +862 -0
  1126. wx/py/tests/test_pseudo.py +70 -0
  1127. wx/py/tests/test_version.py +36 -0
  1128. wx/py/tests/testall.py +22 -0
  1129. wx/py/version.py +7 -0
  1130. wx/ribbon.py +45 -0
  1131. wx/ribbon.pyi +2494 -0
  1132. wx/richtext.py +142 -0
  1133. wx/richtext.pyi +12113 -0
  1134. wx/siplib.cp313-win_amd64.pyd +0 -0
  1135. wx/stc.py +58 -0
  1136. wx/stc.pyi +8463 -0
  1137. wx/svg/__init__.py +364 -0
  1138. wx/svg/_nanosvg.cp313-win_amd64.pyd +0 -0
  1139. wx/tools/__init__.py +18 -0
  1140. wx/tools/dbg.py +268 -0
  1141. wx/tools/genaxmodule.py +50 -0
  1142. wx/tools/helpviewer.py +92 -0
  1143. wx/tools/img2img.py +85 -0
  1144. wx/tools/img2png.py +54 -0
  1145. wx/tools/img2py.py +309 -0
  1146. wx/tools/img2xpm.py +54 -0
  1147. wx/tools/pywxrc.py +949 -0
  1148. wx/tools/wxget.py +254 -0
  1149. wx/tools/wxget_docs_demo.py +186 -0
  1150. wx/wxbase315u_net_vc140_x64.dll +0 -0
  1151. wx/wxbase315u_vc140_x64.dll +0 -0
  1152. wx/wxbase315u_xml_vc140_x64.dll +0 -0
  1153. wx/wxmsw315u_adv_vc140_x64.dll +0 -0
  1154. wx/wxmsw315u_aui_vc140_x64.dll +0 -0
  1155. wx/wxmsw315u_core_vc140_x64.dll +0 -0
  1156. wx/wxmsw315u_gl_vc140_x64.dll +0 -0
  1157. wx/wxmsw315u_html_vc140_x64.dll +0 -0
  1158. wx/wxmsw315u_media_vc140_x64.dll +0 -0
  1159. wx/wxmsw315u_propgrid_vc140_x64.dll +0 -0
  1160. wx/wxmsw315u_qa_vc140_x64.dll +0 -0
  1161. wx/wxmsw315u_ribbon_vc140_x64.dll +0 -0
  1162. wx/wxmsw315u_richtext_vc140_x64.dll +0 -0
  1163. wx/wxmsw315u_stc_vc140_x64.dll +0 -0
  1164. wx/wxmsw315u_webview_vc140_x64.dll +0 -0
  1165. wx/wxmsw315u_xrc_vc140_x64.dll +0 -0
  1166. wx/xml.py +15 -0
  1167. wx/xml.pyi +575 -0
  1168. wx/xrc.py +65 -0
  1169. wx/xrc.pyi +742 -0
  1170. wxPython_zombie-3.1.5.8.dist-info/LICENSE.txt +950 -0
  1171. wxPython_zombie-3.1.5.8.dist-info/METADATA +107 -0
  1172. wxPython_zombie-3.1.5.8.dist-info/RECORD +1175 -0
  1173. wxPython_zombie-3.1.5.8.dist-info/WHEEL +5 -0
  1174. wxPython_zombie-3.1.5.8.dist-info/entry_points.txt +2 -0
  1175. wxPython_zombie-3.1.5.8.dist-info/top_level.txt +1 -0
wx/lib/ogl/basic.py ADDED
@@ -0,0 +1,3991 @@
1
+ # -*- coding: utf-8 -*-
2
+ #----------------------------------------------------------------------------
3
+ # Name: basic.py
4
+ # Purpose: The basic OGL shapes
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
+ # (c) 2021 Zombie
13
+ #----------------------------------------------------------------------------
14
+ """
15
+ The basic shapes for OGL
16
+ """
17
+
18
+ import wx
19
+ import math
20
+
21
+ from .oglmisc import *
22
+
23
+ DragOffsetX = 0.0
24
+ DragOffsetY = 0.0
25
+
26
+
27
+ def OGLInitialize():
28
+ """Initialize OGL.
29
+
30
+ :note: This creates some pens and brushes that the OGL library uses.
31
+ It should be called after the app object has been created, but
32
+ before OGL is used.
33
+ """
34
+ global WhiteBackgroundPen, WhiteBackgroundBrush, TransparentPen
35
+ global BlackForegroundPen, NormalFont
36
+
37
+ WhiteBackgroundPen = wx.Pen(wx.WHITE, 1, wx.PENSTYLE_SOLID)
38
+ WhiteBackgroundBrush = wx.Brush(wx.WHITE, wx.BRUSHSTYLE_SOLID)
39
+
40
+ TransparentPen = wx.Pen(wx.WHITE, 1, wx.PENSTYLE_TRANSPARENT)
41
+ BlackForegroundPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_SOLID)
42
+
43
+ NormalFont = wx.Font(10, wx.FONTFAMILY_SWISS, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL)
44
+
45
+
46
+ def OGLCleanUp():
47
+ """not implemented???"""
48
+ pass
49
+
50
+
51
+ class ShapeTextLine(object):
52
+ """The :class:`ShapeTextLine` class."""
53
+ def __init__(self, the_x, the_y, the_line):
54
+ """
55
+ Default class constructor.
56
+
57
+ :param int `the_x`: the x position
58
+ :param int `the_y`: the y position
59
+ :param str `the_line`: the text
60
+
61
+ """
62
+ self._x = the_x
63
+ self._y = the_y
64
+ self._line = the_line
65
+
66
+ def GetX(self):
67
+ """Get the x position."""
68
+ return self._x
69
+
70
+ def GetY(self):
71
+ """Get the y position."""
72
+ return self._y
73
+
74
+ def SetX(self, x):
75
+ """
76
+ Set the x position.
77
+
78
+ :param int `x`: the x position
79
+
80
+ """
81
+ self._x = x
82
+
83
+ def SetY(self, y):
84
+ """
85
+ Set the y position.
86
+
87
+ :param int `y`: the x position
88
+
89
+ """
90
+ self._y = y
91
+
92
+ def SetText(self, text):
93
+ """
94
+ Set the text.
95
+
96
+ :param str `text`: the text
97
+
98
+ """
99
+ self._line = text
100
+
101
+ def GetText(self):
102
+ """Get the text."""
103
+ return self._line
104
+
105
+
106
+ class ShapeEvtHandler(object):
107
+ """The :class:`ShapeEvtHandler` class."""
108
+ def __init__(self, prev = None, shape = None):
109
+ """
110
+ Default class constructor.
111
+
112
+ :param `pref`: the previous event handler, an instance of
113
+ :class:`ShapeEvtHandler` ???
114
+ :param `shape`: the shape, an instance of :class:`Shape`
115
+
116
+ """
117
+ self._previousHandler = prev
118
+ self._handlerShape = shape
119
+
120
+ def SetShape(self, sh):
121
+ """
122
+ Set associated shape
123
+
124
+ :param `sh`: the shape, an instance of :class:`Shape`
125
+
126
+ """
127
+ self._handlerShape = sh
128
+
129
+ def GetShape(self):
130
+ """Get associated shape."""
131
+ return self._handlerShape
132
+
133
+ def SetPreviousHandler(self, handler):
134
+ """
135
+ Set previous event handler.
136
+
137
+ :param `handler`: the previous handler, an instance of
138
+ :class:`ShapeEvtHandler` ???
139
+
140
+ """
141
+ self._previousHandler = handler
142
+
143
+ def GetPreviousHandler(self):
144
+ """Get previous event handler."""
145
+ return self._previousHandler
146
+
147
+ def OnDelete(self):
148
+ """The delete handler."""
149
+ if self!=self.GetShape():
150
+ del self
151
+
152
+ def OnDraw(self, dc):
153
+ """The draw handler."""
154
+ if self._previousHandler:
155
+ self._previousHandler.OnDraw(dc)
156
+
157
+ def OnMoveLinks(self, dc):
158
+ """The move links handler."""
159
+ if self._previousHandler:
160
+ self._previousHandler.OnMoveLinks(dc)
161
+
162
+ def OnMoveLink(self, dc, moveControlPoints = True):
163
+ """The move link handler."""
164
+ if self._previousHandler:
165
+ self._previousHandler.OnMoveLink(dc, moveControlPoints)
166
+
167
+ def OnDrawContents(self, dc):
168
+ """The draw contents handler."""
169
+ if self._previousHandler:
170
+ self._previousHandler.OnDrawContents(dc)
171
+
172
+ def OnDrawBranches(self, dc, erase = False):
173
+ """The draw branches handler."""
174
+ if self._previousHandler:
175
+ self._previousHandler.OnDrawBranches(dc, erase = erase)
176
+
177
+ def OnSize(self, x, y):
178
+ """The size handler."""
179
+ if self._previousHandler:
180
+ self._previousHandler.OnSize(x, y)
181
+
182
+ def OnMovePre(self, dc, x, y, old_x, old_y, display = True):
183
+ """The pre move handler."""
184
+ if self._previousHandler:
185
+ return self._previousHandler.OnMovePre(dc, x, y, old_x, old_y, display)
186
+ else:
187
+ return True
188
+
189
+ def OnMovePost(self, dc, x, y, old_x, old_y, display = True):
190
+ """The post move handler."""
191
+ if self._previousHandler:
192
+ return self._previousHandler.OnMovePost(dc, x, y, old_x, old_y, display)
193
+ else:
194
+ return True
195
+
196
+ def OnErase(self, dc):
197
+ """The erase handler."""
198
+ if self._previousHandler:
199
+ self._previousHandler.OnErase(dc)
200
+
201
+ def OnEraseContents(self, dc):
202
+ """The erase contents handler."""
203
+ if self._previousHandler:
204
+ self._previousHandler.OnEraseContents(dc)
205
+
206
+ def OnHighlight(self, dc):
207
+ """The highlight handler."""
208
+ if self._previousHandler:
209
+ self._previousHandler.OnHighlight(dc)
210
+
211
+ def OnLeftClick(self, x, y, keys, attachment):
212
+ """The left click handler."""
213
+ if self._previousHandler:
214
+ self._previousHandler.OnLeftClick(x, y, keys, attachment)
215
+
216
+ def OnLeftDoubleClick(self, x, y, keys = 0, attachment = 0):
217
+ """The left double click handler."""
218
+ if self._previousHandler:
219
+ self._previousHandler.OnLeftDoubleClick(x, y, keys, attachment)
220
+
221
+ def OnRightClick(self, x, y, keys = 0, attachment = 0):
222
+ """The right click handler."""
223
+ if self._previousHandler:
224
+ self._previousHandler.OnRightClick(x, y, keys, attachment)
225
+
226
+ def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
227
+ """The drag left handler."""
228
+ if self._previousHandler:
229
+ self._previousHandler.OnDragLeft(draw, x, y, keys, attachment)
230
+
231
+ def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
232
+ """The begin drag left handler."""
233
+ if self._previousHandler:
234
+ self._previousHandler.OnBeginDragLeft(x, y, keys, attachment)
235
+
236
+ def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
237
+ """The end drag left handler."""
238
+ if self._previousHandler:
239
+ self._previousHandler.OnEndDragLeft(x, y, keys, attachment)
240
+
241
+ def OnDragRight(self, draw, x, y, keys = 0, attachment = 0):
242
+ """The drag right handler."""
243
+ if self._previousHandler:
244
+ self._previousHandler.OnDragRight(draw, x, y, keys, attachment)
245
+
246
+ def OnBeginDragRight(self, x, y, keys = 0, attachment = 0):
247
+ """The begin drag right handler."""
248
+ if self._previousHandler:
249
+ self._previousHandler.OnBeginDragRight(x, y, keys, attachment)
250
+
251
+ def OnEndDragRight(self, x, y, keys = 0, attachment = 0):
252
+ """The end drag right handler."""
253
+ if self._previousHandler:
254
+ self._previousHandler.OnEndDragRight(x, y, keys, attachment)
255
+
256
+ # Control points ('handles') redirect control to the actual shape,
257
+ # to make it easier to override sizing behaviour.
258
+ def OnSizingDragLeft(self, pt, draw, x, y, keys = 0, attachment = 0):
259
+ """The sizing drag left handler."""
260
+ if self._previousHandler:
261
+ self._previousHandler.OnSizingDragLeft(pt, draw, x, y, keys, attachment)
262
+
263
+ def OnSizingBeginDragLeft(self, pt, x, y, keys = 0, attachment = 0):
264
+ """The sizing begin drag left handler."""
265
+ if self._previousHandler:
266
+ self._previousHandler.OnSizingBeginDragLeft(pt, x, y, keys, attachment)
267
+
268
+ def OnSizingEndDragLeft(self, pt, x, y, keys = 0, attachment = 0):
269
+ """The sizing end drag left handler."""
270
+ if self._previousHandler:
271
+ self._previousHandler.OnSizingEndDragLeft(pt, x, y, keys, attachment)
272
+
273
+ def OnBeginSize(self, w, h):
274
+ """not implemented???"""
275
+ pass
276
+
277
+ def OnEndSize(self, w, h):
278
+ """not implemented???"""
279
+ pass
280
+
281
+ def OnDrawOutline(self, dc, x, y, w, h):
282
+ """The drag outline handler."""
283
+ if self._previousHandler:
284
+ self._previousHandler.OnDrawOutline(dc, x, y, w, h)
285
+
286
+ def OnDrawControlPoints(self, dc):
287
+ """The draw control points handler."""
288
+ if self._previousHandler:
289
+ self._previousHandler.OnDrawControlPoints(dc)
290
+
291
+ def OnEraseControlPoints(self, dc):
292
+ """The erase control points handler."""
293
+ if self._previousHandler:
294
+ self._previousHandler.OnEraseControlPoints(dc)
295
+
296
+ # Can override this to prevent or intercept line reordering.
297
+ def OnChangeAttachment(self, attachment, line, ordering):
298
+ """The change attachment handler."""
299
+ if self._previousHandler:
300
+ self._previousHandler.OnChangeAttachment(attachment, line, ordering)
301
+
302
+
303
+ class Shape(ShapeEvtHandler):
304
+ """
305
+ The :class:`Shape` is the base class for OGL shapes.
306
+
307
+ The :class:`Shape` is the top-level, abstract object that all other objects
308
+ are derived from. All common functionality is represented by :class:`Shape`
309
+ members, and overriden members that appear in derived classes and have
310
+ behaviour as documented for :class:`Shape`, are not documented separately.
311
+ """
312
+ GraphicsInSizeToContents = False
313
+
314
+ def __init__(self, canvas = None):
315
+ """
316
+ Default class constructor.
317
+
318
+ :param `canvas`: an instance of :class:`~lib.ogl.Canvas`
319
+
320
+ """
321
+ ShapeEvtHandler.__init__(self)
322
+
323
+ self._eventHandler = self
324
+ self.SetShape(self)
325
+ self._id = 0
326
+ self._formatted = False
327
+ self._canvas = canvas
328
+ self._xpos = 0.0
329
+ self._ypos = 0.0
330
+ self._pen = BlackForegroundPen
331
+ self._brush = wx.WHITE_BRUSH
332
+ self._font = NormalFont
333
+ self._textColour = wx.BLACK
334
+ self._textColourName = wx.BLACK
335
+ self._visible = False
336
+ self._selected = False
337
+ self._attachmentMode = ATTACHMENT_MODE_NONE
338
+ self._spaceAttachments = True
339
+ self._disableLabel = False
340
+ self._fixedWidth = False
341
+ self._fixedHeight = False
342
+ self._drawHandles = True
343
+ self._sensitivity = OP_ALL
344
+ self._draggable = True
345
+ self._parent = None
346
+ self._formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT
347
+ self._shadowMode = SHADOW_NONE
348
+ self._shadowOffsetX = 6
349
+ self._shadowOffsetY = 6
350
+ self._shadowBrush = wx.BLACK_BRUSH
351
+ self._textMarginX = 5
352
+ self._textMarginY = 5
353
+ self._regionName = "0"
354
+ self._centreResize = True
355
+ self._maintainAspectRatio = False
356
+ self._highlighted = False
357
+ self._rotation = 0.0
358
+ self._branchNeckLength = 10
359
+ self._branchStemLength = 10
360
+ self._branchSpacing = 10
361
+ self._branchStyle = BRANCHING_ATTACHMENT_NORMAL
362
+
363
+ self._regions = []
364
+ self._lines = []
365
+ self._controlPoints = []
366
+ self._attachmentPoints = []
367
+ self._text = []
368
+ self._children = []
369
+
370
+ # Set up a default region. Much of the above will be put into
371
+ # the region eventually (the duplication is for compatibility)
372
+ region = ShapeRegion()
373
+ region.SetName("0")
374
+ region.SetFont(NormalFont)
375
+ region.SetFormatMode(FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT)
376
+ region.SetColour("BLACK")
377
+ self._regions.append(region)
378
+
379
+ def __str__(self):
380
+ return "<%s.%s>" % (self.__class__.__module__, self.__class__.__name__)
381
+
382
+ def GetClassName(self):
383
+ return str(self.__class__).split(".")[-1][:-2]
384
+
385
+ def Delete(self):
386
+ """
387
+ Fully disconnect this shape from parents, children, the
388
+ canvas, etc.
389
+ """
390
+ if self._parent:
391
+ self._parent.GetChildren().remove(self)
392
+
393
+ for child in self.GetChildren():
394
+ child.Delete()
395
+
396
+ self.ClearText()
397
+ self.ClearRegions()
398
+ self.ClearAttachments()
399
+
400
+ self._handlerShape = None
401
+
402
+ if self._canvas:
403
+ self.RemoveFromCanvas(self._canvas)
404
+
405
+ if self.GetEventHandler():
406
+ self.GetEventHandler().OnDelete()
407
+ self._eventHandler = None
408
+
409
+ def Draggable(self):
410
+ """
411
+ Is shape draggable?
412
+
413
+ :returns: `True` if the shape may be dragged by the user.
414
+ """
415
+ return True
416
+
417
+ def SetShape(self, sh):
418
+ """Set shape ???
419
+
420
+ :param `sh`: an instance of :class:`Shape`
421
+
422
+ """
423
+ self._handlerShape = sh
424
+
425
+ def GetCanvas(self):
426
+ """Get the internal canvas."""
427
+ return self._canvas
428
+
429
+ def GetBranchStyle(self):
430
+ """Get the branch style."""
431
+ return self._branchStyle
432
+
433
+ def GetRotation(self):
434
+ """Return the angle of rotation in radians."""
435
+ return self._rotation
436
+
437
+ def SetRotation(self, rotation):
438
+ """Set rotation
439
+
440
+ :param int `rotation`: rotation
441
+
442
+ """
443
+ self._rotation = rotation
444
+
445
+ def SetHighlight(self, hi, recurse = False):
446
+ """Set the highlight for a shape. Shape highlighting is unimplemented."""
447
+ self._highlighted = hi
448
+ if recurse:
449
+ for shape in self._children:
450
+ shape.SetHighlight(hi, recurse)
451
+
452
+ def SetSensitivityFilter(self, sens = OP_ALL, recursive = False):
453
+ """
454
+ Set the shape to be sensitive or insensitive to specific mouse
455
+ operations.
456
+
457
+ :param `sens`: is a bitlist of the following:
458
+
459
+ ========================== ===================
460
+ Mouse operation Description
461
+ ========================== ===================
462
+ `OP_CLICK_LEFT` left clicked
463
+ `OP_CLICK_RIGHT` right clicked
464
+ `OP_DRAG_LEFT` left drag
465
+ `OP_DRAG_RIGHT` right drag
466
+ `OP_ALL` all of the above
467
+ ========================== ===================
468
+
469
+ :param `recursive`: if `True` recurse through children
470
+
471
+ """
472
+ self._draggable = sens & OP_DRAG_LEFT
473
+
474
+ self._sensitivity = sens
475
+ if recursive:
476
+ for shape in self._children:
477
+ shape.SetSensitivityFilter(sens, True)
478
+
479
+ def SetDraggable(self, drag, recursive = False):
480
+ """Set the shape to be draggable or not draggable.
481
+
482
+ :param `drag`: if `True` make shape draggable
483
+ :param `recursive`: if `True` recurse through children
484
+
485
+ """
486
+ self._draggable = drag
487
+ if drag:
488
+ self._sensitivity |= OP_DRAG_LEFT
489
+ elif self._sensitivity & OP_DRAG_LEFT:
490
+ self._sensitivity -= OP_DRAG_LEFT
491
+
492
+ if recursive:
493
+ for shape in self._children:
494
+ shape.SetDraggable(drag, True)
495
+
496
+ def SetDrawHandles(self, drawH):
497
+ """
498
+ Set the drawHandles flag for this shape and all descendants.
499
+
500
+ :param `drawH`: if `True` (the default), any handles (control points)
501
+ will be drawn. Otherwise, the handles will not be drawn.
502
+
503
+ """
504
+ self._drawHandles = drawH
505
+ for shape in self._children:
506
+ shape.SetDrawHandles(drawH)
507
+
508
+ def SetShadowMode(self, mode, redraw = False):
509
+ """
510
+ Set the shadow mode (whether a shadow is drawn or not).
511
+
512
+ :param `mode`: can be one of the following:
513
+
514
+ =============================== ===========================
515
+ Shadow mode Description
516
+ =============================== ===========================
517
+ `SHADOW_NONE` No shadow (the default)
518
+ `SHADOW_LEFT` Shadow on the left side
519
+ `SHADOW_RIGHT` Shadow on the right side
520
+ =============================== ===========================
521
+
522
+ """
523
+ if redraw and self.GetCanvas():
524
+ dc = wx.MemoryDC()
525
+ dc.SelectObject(self.GetCanvas().GetBuffer())
526
+ self.GetCanvas().PrepareDC(dc)
527
+ self.Erase(dc)
528
+ self._shadowMode = mode
529
+ self.Draw(dc)
530
+ else:
531
+ self._shadowMode = mode
532
+
533
+ def GetShadowMode(self):
534
+ """Get the current shadow mode setting."""
535
+ return self._shadowMode
536
+
537
+ def SetCanvas(self, theCanvas):
538
+ """
539
+ Set the canvas, identical to Shape.Attach.
540
+
541
+ :param `theCanvas`: an instance of :class:`~lib.ogl.Canvas`
542
+
543
+ """
544
+ self._canvas = theCanvas
545
+ for shape in self._children:
546
+ shape.SetCanvas(theCanvas)
547
+
548
+ def AddToCanvas(self, theCanvas, addAfter = None):
549
+ """
550
+ Add the shape to the canvas's shape list.
551
+
552
+ :param `theCanvas`: an instance of :class:`~lib.ogl.Canvas`
553
+ :param `addAfter`: if non-NULL, will add the shape after this shape
554
+
555
+ """
556
+ theCanvas.AddShape(self, addAfter)
557
+
558
+ lastImage = self
559
+ for object in self._children:
560
+ object.AddToCanvas(theCanvas, lastImage)
561
+ lastImage = object
562
+
563
+ def InsertInCanvas(self, theCanvas):
564
+ """
565
+ Insert the shape at the front of the shape list of canvas.
566
+
567
+ :param `theCanvas`: an instance of :class:`~lib.ogl.Canvas`
568
+
569
+ """
570
+ theCanvas.InsertShape(self)
571
+
572
+ lastImage = self
573
+ for object in self._children:
574
+ object.AddToCanvas(theCanvas, lastImage)
575
+ lastImage = object
576
+
577
+ def RemoveFromCanvas(self, theCanvas):
578
+ """
579
+ Remove the shape from the canvas.
580
+
581
+ :param `theCanvas`: an instance of :class:`~lib.ogl.Canvas`
582
+
583
+ """
584
+ if self.Selected():
585
+ self.Select(False)
586
+
587
+ self._canvas = None
588
+ theCanvas.RemoveShape(self)
589
+ for object in self._children:
590
+ object.RemoveFromCanvas(theCanvas)
591
+
592
+ def ClearAttachments(self):
593
+ """Clear internal custom attachment point shapes (of class
594
+ :class:`~lib.ogl.AttachmentPoint`)
595
+ """
596
+ self._attachmentPoints = []
597
+
598
+ def ClearText(self, regionId = 0):
599
+ """
600
+ Clear the text from the specified text region.
601
+
602
+ :param `regionId`: the region identifier
603
+
604
+ """
605
+ if regionId == 0:
606
+ self._text = ""
607
+ if regionId < len(self._regions):
608
+ self._regions[regionId].ClearText()
609
+
610
+ def ClearRegions(self):
611
+ """Clear the ShapeRegions from the shape."""
612
+ self._regions = []
613
+
614
+ def AddRegion(self, region):
615
+ """Add a region to the shape."""
616
+ self._regions.append(region)
617
+
618
+ def SetDefaultRegionSize(self):
619
+ """Set the default region to be consistent with the shape size."""
620
+ if not self._regions:
621
+ return
622
+ w, h = self.GetBoundingBoxMax()
623
+ self._regions[0].SetSize(w, h)
624
+
625
+ def HitTest(self, x, y):
626
+ """
627
+ Given a point on a canvas, returns `True` if the point was on the
628
+ shape, and returns the nearest attachment point and distance from
629
+ the given point and target.
630
+
631
+ :param `x`: the x position
632
+ :param `y`: the y position
633
+
634
+ """
635
+ width, height = self.GetBoundingBoxMax()
636
+ if abs(width) < 4:
637
+ width = 4.0
638
+ if abs(height) < 4:
639
+ height = 4.0
640
+
641
+ width += 4 # Allowance for inaccurate mousing
642
+ height += 4
643
+
644
+ left = self._xpos - width / 2.0
645
+ top = self._ypos - height / 2.0
646
+ right = self._xpos + width / 2.0
647
+ bottom = self._ypos + height / 2.0
648
+
649
+ nearest_attachment = 0
650
+
651
+ # If within the bounding box, check the attachment points
652
+ # within the object.
653
+ if x >= left and x <= right and y >= top and y <= bottom:
654
+ n = self.GetNumberOfAttachments()
655
+ nearest = 999999
656
+
657
+ # GetAttachmentPosition[Edge] takes a logical attachment position,
658
+ # i.e. if it's rotated through 90%, position 0 is East-facing.
659
+
660
+ for i in range(n):
661
+ e = self.GetAttachmentPositionEdge(i)
662
+ if e:
663
+ xp, yp = e
664
+ l = math.sqrt(((xp - x) * (xp - x)) + (yp - y) * (yp - y))
665
+ if l < nearest:
666
+ nearest = l
667
+ nearest_attachment = i
668
+
669
+ return nearest_attachment, nearest
670
+ return False
671
+
672
+ # Format a text string according to the region size, adding
673
+ # strings with positions to region text list
674
+
675
+ def FormatText(self, dc, s, i = 0):
676
+ """
677
+ Reformat the given text region; defaults to formatting the
678
+ default region.
679
+
680
+ :param `dc`: the device contexr
681
+ :param str `s`: the text string
682
+ :param int `i`: the region identifier
683
+
684
+ """
685
+ self.ClearText(i)
686
+
687
+ if not self._regions:
688
+ return
689
+
690
+ if i >= len(self._regions):
691
+ return
692
+
693
+ region = self._regions[i]
694
+ region._regionText = s
695
+ dc.SetFont(region.GetFont())
696
+
697
+ w, h = region.GetSize()
698
+
699
+ stringList = FormatText(dc, s, (w - 2 * self._textMarginX), (h - 2 * self._textMarginY), region.GetFormatMode())
700
+ for s in stringList:
701
+ line = ShapeTextLine(0.0, 0.0, s)
702
+ region.GetFormattedText().append(line)
703
+
704
+ actualW = w
705
+ actualH = h
706
+ # Don't try to resize an object with more than one image (this
707
+ # case should be dealt with by overriden handlers)
708
+ if (region.GetFormatMode() & FORMAT_SIZE_TO_CONTENTS) and \
709
+ len(region.GetFormattedText()) and \
710
+ len(self._regions) == 1 and \
711
+ not Shape.GraphicsInSizeToContents:
712
+
713
+ actualW, actualH = GetCentredTextExtent(dc, region.GetFormattedText())
714
+ if actualW + 2 * self._textMarginX != w or actualH + 2 * self._textMarginY != h:
715
+ # If we are a descendant of a composite, must make sure
716
+ # the composite gets resized properly
717
+
718
+ topAncestor = self.GetTopAncestor()
719
+ if topAncestor != self:
720
+ Shape.GraphicsInSizeToContents = True
721
+
722
+ composite = topAncestor
723
+ composite.Erase(dc)
724
+ self.SetSize(actualW + 2 * self._textMarginX, actualH + 2 * self._textMarginY)
725
+ self.Move(dc, self._xpos, self._ypos)
726
+ composite.CalculateSize()
727
+ if composite.Selected():
728
+ composite.DeleteControlPoints(dc)
729
+ composite.MakeControlPoints()
730
+ composite.MakeMandatoryControlPoints()
731
+ # Where infinite recursion might happen if we didn't stop it
732
+ composite.Draw(dc)
733
+ Shape.GraphicsInSizeToContents = False
734
+ else:
735
+ self.Erase(dc)
736
+
737
+ self.SetSize(actualW + 2 * self._textMarginX, actualH + 2 * self._textMarginY)
738
+ self.Move(dc, self._xpos, self._ypos)
739
+ self.EraseContents(dc)
740
+ CentreText(dc, region.GetFormattedText(), self._xpos, self._ypos, actualW - 2 * self._textMarginX, actualH - 2 * self._textMarginY, region.GetFormatMode())
741
+ self._formatted = True
742
+
743
+ def Recentre(self, dc):
744
+ """
745
+ Recentre (or other formatting) all the text regions for this shape.
746
+ """
747
+ w, h = self.GetBoundingBoxMin()
748
+ for region in self._regions:
749
+ CentreText(dc, region.GetFormattedText(), self._xpos, self._ypos, w - 2 * self._textMarginX, h - 2 * self._textMarginY, region.GetFormatMode())
750
+
751
+ def GetPerimeterPoint(self, x1, y1, x2, y2):
752
+ """
753
+ Get the point at which the line from (x1, y1) to (x2, y2) hits
754
+ the shape.
755
+
756
+ :param `x1`: the x1 position
757
+ :param `y1`: the y1 position
758
+ :param `x2`: the x2 position
759
+ :param `y2`: the y2 position
760
+
761
+ :returns: `False` if the line doesn't hit the perimeter.
762
+
763
+ """
764
+ return False
765
+
766
+ def SetPen(self, the_pen):
767
+ """Set the pen for drawing the shape's outline."""
768
+ self._pen = the_pen
769
+
770
+ def SetBrush(self, the_brush):
771
+ """Set the brush for filling the shape's shape."""
772
+ self._brush = the_brush
773
+
774
+ # Get the top - most (non-division) ancestor, or self
775
+ def GetTopAncestor(self):
776
+ """
777
+ Return the top-most ancestor of this shape (the root of
778
+ the composite).
779
+ """
780
+ if not self.GetParent():
781
+ return self
782
+
783
+ if isinstance(self.GetParent(), DivisionShape):
784
+ return self
785
+ return self.GetParent().GetTopAncestor()
786
+
787
+ # Region functions
788
+ def SetFont(self, the_font, regionId = 0):
789
+ """
790
+ Set the font for the specified text region.
791
+
792
+ :param `the_font`: an instance of :class:`wx.Font` ???
793
+ :param `regionId`: the region identifier
794
+
795
+ """
796
+ self._font = the_font
797
+ if regionId < len(self._regions):
798
+ self._regions[regionId].SetFont(the_font)
799
+
800
+ def GetFont(self, regionId = 0):
801
+ """
802
+ Get the font for the specified text region.
803
+
804
+ :param `regionId`: the region identifier
805
+
806
+ """
807
+ if regionId >= len(self._regions):
808
+ return None
809
+ return self._regions[regionId].GetFont()
810
+
811
+ def SetFormatMode(self, mode, regionId = 0):
812
+ """
813
+ Set the format mode of the region.
814
+
815
+ :param `mode`: can be a bit list of the following
816
+
817
+ ============================== ==============================
818
+ Format mode Description
819
+ ============================== ==============================
820
+ `FORMAT_NONE` No formatting
821
+ `FORMAT_CENTRE_HORIZ` Horizontal centring
822
+ `FORMAT_CENTRE_VERT` Vertical centring
823
+ ============================== ==============================
824
+
825
+ :param `regionId`: the region identifier, default=0
826
+
827
+ """
828
+ if regionId < len(self._regions):
829
+ self._regions[regionId].SetFormatMode(mode)
830
+
831
+ def GetFormatMode(self, regionId = 0):
832
+ """
833
+ Get the format mode.
834
+
835
+ :param `regionId`: the region identifier, default=0
836
+
837
+ """
838
+ if regionId >= len(self._regions):
839
+ return 0
840
+ return self._regions[regionId].GetFormatMode()
841
+
842
+ def SetTextColour(self, the_colour, regionId = 0):
843
+ """
844
+ Set the colour for the specified text region.
845
+
846
+ :param str `the_colour`: a valid colour name,
847
+ see :class:`wx.ColourDatabase`
848
+ :param `regionId`: the region identifier
849
+
850
+ """
851
+ self._textColour = wx.TheColourDatabase.Find(the_colour)
852
+ self._textColourName = the_colour
853
+
854
+ if regionId < len(self._regions):
855
+ self._regions[regionId].SetColour(the_colour)
856
+
857
+ def GetTextColour(self, regionId = 0):
858
+ """
859
+ Get the colour for the specified text region.
860
+
861
+ :param `regionId`: the region identifier
862
+
863
+ """
864
+ if regionId >= len(self._regions):
865
+ return ""
866
+ return self._regions[regionId].GetColour()
867
+
868
+ def SetRegionName(self, name, regionId = 0):
869
+ """
870
+ Set the name for this region.
871
+
872
+ :param str `name`: the name to set
873
+ :param `regionId`: the region identifier
874
+
875
+ :note: The name for a region is unique within the scope of the whole
876
+ composite, whereas a region id is unique only for a single image.
877
+
878
+ """
879
+ if regionId < len(self._regions):
880
+ self._regions[regionId].SetName(name)
881
+
882
+ def GetRegionName(self, regionId = 0):
883
+ """
884
+ Get the region's name.
885
+
886
+ :param `regionId`: the region identifier
887
+
888
+ :note: A region's name can be used to uniquely determine a region within
889
+ an entire composite image hierarchy. See also
890
+ :meth:`~lib.ogl.Shape.SetRegionName`.
891
+
892
+ """
893
+ if regionId >= len(self._regions):
894
+ return ""
895
+ return self._regions[regionId].GetName()
896
+
897
+ def GetRegionId(self, name):
898
+ """
899
+ Get the region's identifier by name.
900
+
901
+ :param str `name`: the regions name
902
+
903
+ :note: This is not unique for within an entire composite, but is unique
904
+ for the image.
905
+
906
+ """
907
+ for i, r in enumerate(self._regions):
908
+ if r.GetName() == name:
909
+ return i
910
+ return -1
911
+
912
+ # Name all _regions in all subimages recursively
913
+ def NameRegions(self, parentName=""):
914
+ """
915
+ Make unique names for all the regions in a shape or composite shape.
916
+
917
+ :param str `parentName`: a prefix for the region names
918
+
919
+ """
920
+ n = self.GetNumberOfTextRegions()
921
+ for i in range(n):
922
+ if parentName:
923
+ buff = parentName+"."+str(i)
924
+ else:
925
+ buff = str(i)
926
+ self.SetRegionName(buff, i)
927
+
928
+ for j, child in enumerate(self._children):
929
+ if parentName:
930
+ buff = parentName+"."+str(j)
931
+ else:
932
+ buff = str(j)
933
+ child.NameRegions(buff)
934
+
935
+ # Get a region by name, possibly looking recursively into composites
936
+ def FindRegion(self, name):
937
+ """
938
+ Find the actual image ('this' if non-composite) and region id
939
+ for the given region name.
940
+
941
+ :param str `name`: the region name
942
+
943
+ """
944
+ id = self.GetRegionId(name)
945
+ if id > -1:
946
+ return self, id
947
+
948
+ for child in self._children:
949
+ actualImage, regionId = child.FindRegion(name)
950
+ if actualImage:
951
+ return actualImage, regionId
952
+
953
+ return None, -1
954
+
955
+ # Finds all region names for this image (composite or simple).
956
+ def FindRegionNames(self):
957
+ """Get a list of all region names for this image (composite or simple)."""
958
+ list = []
959
+ n = self.GetNumberOfTextRegions()
960
+ for i in range(n):
961
+ list.append(self.GetRegionName(i))
962
+
963
+ for child in self._children:
964
+ list += child.FindRegionNames()
965
+
966
+ return list
967
+
968
+ def AssignNewIds(self):
969
+ """Assign new ids to this image and its children."""
970
+ self._id = wx.NewIdRef()
971
+ for child in self._children:
972
+ child.AssignNewIds()
973
+
974
+ def OnDraw(self, dc):
975
+ """not implemented???"""
976
+ pass
977
+
978
+ def OnMoveLinks(self, dc):
979
+ """The move links handler."""
980
+ # Want to set the ends of all attached links
981
+ # to point to / from this object
982
+
983
+ for line in self._lines:
984
+ line.GetEventHandler().OnMoveLink(dc)
985
+
986
+ def OnDrawContents(self, dc):
987
+ """The draw contents handler."""
988
+ if not self._regions:
989
+ return
990
+
991
+ bound_x, bound_y = self.GetBoundingBoxMin()
992
+
993
+ if self._pen:
994
+ dc.SetPen(self._pen)
995
+
996
+ for region in self._regions:
997
+ if region.GetFont():
998
+ dc.SetFont(region.GetFont())
999
+
1000
+ dc.SetTextForeground(region.GetActualColourObject())
1001
+ dc.SetBackgroundMode(wx.TRANSPARENT)
1002
+ if not self._formatted:
1003
+ CentreText(dc, region.GetFormattedText(), self._xpos, self._ypos, bound_x - 2 * self._textMarginX, bound_y - 2 * self._textMarginY, region.GetFormatMode())
1004
+ self._formatted = True
1005
+
1006
+ if not self.GetDisableLabel():
1007
+ DrawFormattedText(dc, region.GetFormattedText(), self._xpos, self._ypos, bound_x - 2 * self._textMarginX, bound_y - 2 * self._textMarginY, region.GetFormatMode())
1008
+
1009
+ def DrawContents(self, dc):
1010
+ """
1011
+ Draw the internal graphic of the shape (such as text).
1012
+
1013
+ Do not override this function: override OnDrawContents, which
1014
+ is called by this function.
1015
+ """
1016
+ self.GetEventHandler().OnDrawContents(dc)
1017
+
1018
+ def OnSize(self, x, y):
1019
+ """not implemented???"""
1020
+ pass
1021
+
1022
+ def OnMovePre(self, dc, x, y, old_x, old_y, display = True):
1023
+ return True
1024
+
1025
+ def OnErase(self, dc):
1026
+ """The erase handler."""
1027
+ if not self._visible:
1028
+ return
1029
+
1030
+ # Erase links
1031
+ for line in self._lines:
1032
+ line.GetEventHandler().OnErase(dc)
1033
+
1034
+ self.GetEventHandler().OnEraseContents(dc)
1035
+
1036
+ def OnEraseContents(self, dc):
1037
+ """The erase contents handler."""
1038
+ if not self._visible:
1039
+ return
1040
+
1041
+ xp, yp = self.GetX(), self.GetY()
1042
+ minX, minY = self.GetBoundingBoxMin()
1043
+ maxX, maxY = self.GetBoundingBoxMax()
1044
+
1045
+ topLeftX = xp - maxX / 2.0 - 2
1046
+ topLeftY = yp - maxY / 2.0 - 2
1047
+
1048
+ penWidth = 0
1049
+ if self._pen:
1050
+ penWidth = self._pen.GetWidth()
1051
+
1052
+ dc.SetPen(self.GetBackgroundPen())
1053
+ dc.SetBrush(self.GetBackgroundBrush())
1054
+
1055
+ dc.DrawRectangle(*map(int, (topLeftX - penWidth, topLeftY - penWidth, maxX + penWidth * 2 + 4, maxY + penWidth * 2 + 4)))
1056
+
1057
+ def EraseLinks(self, dc, attachment = -1, recurse = False):
1058
+ """
1059
+ Erase links attached to this shape, but do not repair damage
1060
+ caused to other shapes.
1061
+
1062
+ :param `dc`: the device context
1063
+ :param `attachment`: ???
1064
+ :param `recurse`: if `True` recurse through the children
1065
+
1066
+ """
1067
+ if not self._visible:
1068
+ return
1069
+
1070
+ for line in self._lines:
1071
+ if attachment == -1 or (line.GetTo() == self and line.GetAttachmentTo() == attachment or line.GetFrom() == self and line.GetAttachmentFrom() == attachment):
1072
+ line.GetEventHandler().OnErase(dc)
1073
+
1074
+ if recurse:
1075
+ for child in self._children:
1076
+ child.EraseLinks(dc, attachment, recurse)
1077
+
1078
+ def DrawLinks(self, dc, attachment = -1, recurse = False):
1079
+ """
1080
+ Draws any lines linked to this shape.
1081
+
1082
+ :param `dc`: the device context
1083
+ :param `attachment`: ???
1084
+ :param `recurse`: if `True` recurse through the children
1085
+
1086
+ """
1087
+ if not self._visible:
1088
+ return
1089
+
1090
+ for line in self._lines:
1091
+ if attachment == -1 or (line.GetTo() == self and line.GetAttachmentTo() == attachment or line.GetFrom() == self and line.GetAttachmentFrom() == attachment):
1092
+ line.Draw(dc)
1093
+
1094
+ if recurse:
1095
+ for child in self._children:
1096
+ child.DrawLinks(dc, attachment, recurse)
1097
+
1098
+ # Returns TRUE if pt1 <= pt2 in the sense that one point comes before
1099
+ # another on an edge of the shape.
1100
+ # attachmentPoint is the attachment point (= side) in question.
1101
+
1102
+ # This is the default, rectangular implementation.
1103
+ def AttachmentSortTest(self, attachmentPoint, pt1, pt2):
1104
+ """
1105
+ Return TRUE if pt1 is less than or equal to pt2, in the sense
1106
+ that one point comes before another on an edge of the shape.
1107
+
1108
+ attachment is the attachment point (side) in question.
1109
+
1110
+ This function is used in Shape.MoveLineToNewAttachment to determine
1111
+ the new line ordering.
1112
+ """
1113
+ physicalAttachment = self.LogicalToPhysicalAttachment(attachmentPoint)
1114
+ if physicalAttachment in [0, 2]:
1115
+ return pt1[0] <= pt2[0]
1116
+ elif physicalAttachment in [1, 3]:
1117
+ return pt1[1] <= pt2[1]
1118
+
1119
+ return False
1120
+
1121
+ def MoveLineToNewAttachment(self, dc, to_move, x, y):
1122
+ """
1123
+ Move the given line (which must already be attached to the shape)
1124
+ to a different attachment point on the shape, or a different order
1125
+ on the same attachment.
1126
+
1127
+ Calls Shape.AttachmentSortTest and then
1128
+ ShapeEvtHandler.OnChangeAttachment.
1129
+ """
1130
+ if self.GetAttachmentMode() == ATTACHMENT_MODE_NONE:
1131
+ return False
1132
+
1133
+ # Is (x, y) on this object? If so, find the new attachment point
1134
+ # the user has moved the point to
1135
+ hit = self.HitTest(x, y)
1136
+ if not hit:
1137
+ return False
1138
+
1139
+ newAttachment, distance = hit
1140
+
1141
+ self.EraseLinks(dc)
1142
+
1143
+ if to_move.GetTo() == self:
1144
+ oldAttachment = to_move.GetAttachmentTo()
1145
+ else:
1146
+ oldAttachment = to_move.GetAttachmentFrom()
1147
+
1148
+ # The links in a new ordering
1149
+ # First, add all links to the new list
1150
+ newOrdering = self._lines[:]
1151
+
1152
+ # Delete the line object from the list of links; we're going to move
1153
+ # it to another position in the list
1154
+ del newOrdering[newOrdering.index(to_move)]
1155
+
1156
+ old_x = -99999.9
1157
+ old_y = -99999.9
1158
+
1159
+ found = False
1160
+
1161
+ for line in newOrdering:
1162
+ if line.GetTo() == self and oldAttachment == line.GetAttachmentTo() or \
1163
+ line.GetFrom() == self and oldAttachment == line.GetAttachmentFrom():
1164
+ startX, startY, endX, endY = line.GetEnds()
1165
+ if line.GetTo() == self:
1166
+ xp = endX
1167
+ yp = endY
1168
+ else:
1169
+ xp = startX
1170
+ yp = startY
1171
+
1172
+ thisPoint = wx.RealPoint(xp, yp)
1173
+ lastPoint = wx.RealPoint(old_x, old_y)
1174
+ newPoint = wx.RealPoint(x, y)
1175
+
1176
+ if self.AttachmentSortTest(newAttachment, newPoint, thisPoint) and self.AttachmentSortTest(newAttachment, lastPoint, newPoint):
1177
+ found = True
1178
+ newOrdering.insert(newOrdering.index(line), to_move)
1179
+
1180
+ old_x = xp
1181
+ old_y = yp
1182
+ if found:
1183
+ break
1184
+
1185
+ if not found:
1186
+ newOrdering.append(to_move)
1187
+
1188
+ self.GetEventHandler().OnChangeAttachment(newAttachment, to_move, newOrdering)
1189
+ return True
1190
+
1191
+ def OnChangeAttachment(self, attachment, line, ordering):
1192
+ """Change attachment handler."""
1193
+ if line.GetTo() == self:
1194
+ line.SetAttachmentTo(attachment)
1195
+ else:
1196
+ line.SetAttachmentFrom(attachment)
1197
+
1198
+ self.ApplyAttachmentOrdering(ordering)
1199
+
1200
+ dc = wx.MemoryDC()
1201
+ dc.SelectObject(self.GetCanvas().GetBuffer())
1202
+ self.GetCanvas().PrepareDC(dc)
1203
+ self.MoveLinks(dc)
1204
+
1205
+ if not self.GetCanvas().GetQuickEditMode():
1206
+ self.GetCanvas().Redraw(dc)
1207
+
1208
+ # Reorders the lines according to the given list
1209
+ def ApplyAttachmentOrdering(self, linesToSort):
1210
+ """
1211
+ Apply the line ordering in linesToSort to the shape, to reorder
1212
+ the way lines are attached.
1213
+ """
1214
+ linesStore = self._lines[:]
1215
+
1216
+ self._lines = []
1217
+
1218
+ for line in linesToSort:
1219
+ if line in linesStore:
1220
+ del linesStore[linesStore.index(line)]
1221
+ self._lines.append(line)
1222
+
1223
+ # Now add any lines that haven't been listed in linesToSort
1224
+ self._lines += linesStore
1225
+
1226
+ def SortLines(self, attachment, linesToSort):
1227
+ """
1228
+ Reorder the lines coming into the node image at this attachment
1229
+ position, in the order in which they appear in linesToSort.
1230
+
1231
+ Any remaining lines not in the list will be added to the end.
1232
+ """
1233
+ # This is a temporary store of all the lines at this attachment
1234
+ # point. We'll tick them off as we've processed them.
1235
+ linesAtThisAttachment = []
1236
+
1237
+ for line in self._lines[:]:
1238
+ if line.GetTo() == self and line.GetAttachmentTo() == attachment or \
1239
+ line.GetFrom() == self and line.GetAttachmentFrom() == attachment:
1240
+ linesAtThisAttachment.append(line)
1241
+ del self._lines[self._lines.index(line)]
1242
+
1243
+ for line in linesToSort:
1244
+ if line in linesAtThisAttachment:
1245
+ # Done this one
1246
+ del linesAtThisAttachment[linesAtThisAttachment.index(line)]
1247
+ self._lines.append(line)
1248
+
1249
+ # Now add any lines that haven't been listed in linesToSort
1250
+ self._lines += linesAtThisAttachment
1251
+
1252
+ def OnHighlight(self, dc):
1253
+ """not implemented???"""
1254
+ pass
1255
+
1256
+ def OnLeftClick(self, x, y, keys = 0, attachment = 0):
1257
+ """The left click handler."""
1258
+ if self._sensitivity & OP_CLICK_LEFT != OP_CLICK_LEFT:
1259
+ if self._parent:
1260
+ attachment, dist = self._parent.HitTest(x, y)
1261
+ self._parent.GetEventHandler().OnLeftClick(x, y, keys, attachment)
1262
+
1263
+ def OnRightClick(self, x, y, keys = 0, attachment = 0):
1264
+ """The right click handler."""
1265
+ if self._sensitivity & OP_CLICK_RIGHT != OP_CLICK_RIGHT:
1266
+ attachment, dist = self._parent.HitTest(x, y)
1267
+ self._parent.GetEventHandler().OnRightClick(x, y, keys, attachment)
1268
+
1269
+ def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
1270
+ """The drag left handler."""
1271
+ if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
1272
+ if self._parent:
1273
+ hit = self._parent.HitTest(x, y)
1274
+ if hit:
1275
+ attachment, dist = hit
1276
+ self._parent.GetEventHandler().OnDragLeft(draw, x, y, keys, attachment)
1277
+ return
1278
+
1279
+ dc = wx.ClientDC(self.GetCanvas())
1280
+ self.GetCanvas().PrepareDC(dc)
1281
+ dc.SetLogicalFunction(OGLRBLF)
1282
+
1283
+ dottedPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)
1284
+
1285
+ dc.SetPen(dottedPen)
1286
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
1287
+
1288
+ xx = x + DragOffsetX
1289
+ yy = y + DragOffsetY
1290
+
1291
+ xx, yy = self._canvas.Snap(xx, yy)
1292
+ w, h = self.GetBoundingBoxMax()
1293
+ self.GetEventHandler().OnDrawOutline(dc, xx, yy, w, h)
1294
+
1295
+ def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
1296
+ """The begin drag left handler."""
1297
+ global DragOffsetX, DragOffsetY
1298
+
1299
+ if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
1300
+ if self._parent:
1301
+ hit = self._parent.HitTest(x, y)
1302
+ if hit:
1303
+ attachment, dist = hit
1304
+ self._parent.GetEventHandler().OnBeginDragLeft(x, y, keys, attachment)
1305
+ return
1306
+
1307
+ DragOffsetX = self._xpos - x
1308
+ DragOffsetY = self._ypos - y
1309
+
1310
+ dc = wx.ClientDC(self.GetCanvas())
1311
+ self.GetCanvas().PrepareDC(dc)
1312
+ dc.SetLogicalFunction(OGLRBLF)
1313
+
1314
+ # New policy: don't erase shape until end of drag.
1315
+ # self.Erase(dc)
1316
+ xx = x + DragOffsetX
1317
+ yy = y + DragOffsetY
1318
+ xx, yy = self._canvas.Snap(xx, yy)
1319
+
1320
+ dottedPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)
1321
+ dc.SetPen(dottedPen)
1322
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
1323
+
1324
+ w, h = self.GetBoundingBoxMax()
1325
+ self.GetEventHandler().OnDrawOutline(dc, xx, yy, w, h)
1326
+ self._canvas.CaptureMouse()
1327
+
1328
+ def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
1329
+ """The end drag left handler."""
1330
+ if self._canvas.HasCapture():
1331
+ self._canvas.ReleaseMouse()
1332
+ if self._sensitivity & OP_DRAG_LEFT != OP_DRAG_LEFT:
1333
+ if self._parent:
1334
+ hit = self._parent.HitTest(x, y)
1335
+ if hit:
1336
+ attachment, dist = hit
1337
+ self._parent.GetEventHandler().OnEndDragLeft(x, y, keys, attachment)
1338
+ return
1339
+
1340
+ dc = wx.ClientDC(self.GetCanvas())
1341
+ self.GetCanvas().PrepareDC(dc)
1342
+ dc.SetLogicalFunction(wx.COPY)
1343
+
1344
+ xx = x + DragOffsetX
1345
+ yy = y + DragOffsetY
1346
+ xx, yy = self._canvas.Snap(xx, yy)
1347
+
1348
+ # New policy: erase shape at end of drag.
1349
+ self.Erase(dc)
1350
+
1351
+ self.Move(dc, xx, yy)
1352
+ if self._canvas and not self._canvas.GetQuickEditMode():
1353
+ self._canvas.Redraw(dc)
1354
+
1355
+ def OnDragRight(self, draw, x, y, keys = 0, attachment = 0):
1356
+ """The drag right handler."""
1357
+ if self._sensitivity & OP_DRAG_RIGHT != OP_DRAG_RIGHT:
1358
+ if self._parent:
1359
+ attachment, dist = self._parent.HitTest(x, y)
1360
+ self._parent.GetEventHandler().OnDragRight(draw, x, y, keys, attachment)
1361
+ return
1362
+
1363
+ def OnBeginDragRight(self, x, y, keys = 0, attachment = 0):
1364
+ """The begin drag right handler."""
1365
+ if self._sensitivity & OP_DRAG_RIGHT != OP_DRAG_RIGHT:
1366
+ if self._parent:
1367
+ attachment, dist = self._parent.HitTest(x, y)
1368
+ self._parent.GetEventHandler().OnBeginDragRight(x, y, keys, attachment)
1369
+ return
1370
+
1371
+ def OnEndDragRight(self, x, y, keys = 0, attachment = 0):
1372
+ """The end drag right handler."""
1373
+ if self._sensitivity & OP_DRAG_RIGHT != OP_DRAG_RIGHT:
1374
+ if self._parent:
1375
+ attachment, dist = self._parent.HitTest(x, y)
1376
+ self._parent.GetEventHandler().OnEndDragRight(x, y, keys, attachment)
1377
+ return
1378
+
1379
+ def OnDrawOutline(self, dc, x, y, w, h):
1380
+ """The draw outline handler."""
1381
+ points = [[x - w / 2.0, y - h / 2.0],
1382
+ [x + w / 2.0, y - h / 2.0],
1383
+ [x + w / 2.0, y + h / 2.0],
1384
+ [x - w / 2.0, y + h / 2.0],
1385
+ [x - w / 2.0, y - h / 2.0],
1386
+ ]
1387
+
1388
+ dc.DrawLines(points)
1389
+
1390
+ def Attach(self, can):
1391
+ """Set the shape's internal canvas pointer to point to the given canvas."""
1392
+ self._canvas = can
1393
+
1394
+ def Detach(self):
1395
+ """Disassociates the shape from its canvas."""
1396
+ self._canvas = None
1397
+
1398
+ def Move(self, dc, x, y, display = True):
1399
+ """
1400
+ Move the shape to the given position.
1401
+
1402
+ :param `dc`: the device context
1403
+ :param `x`: the x position
1404
+ :param `y`: the y position
1405
+ :param `display`: if `True` redraw
1406
+
1407
+ """
1408
+ old_x = self._xpos
1409
+ old_y = self._ypos
1410
+
1411
+ if not self.GetEventHandler().OnMovePre(dc, x, y, old_x, old_y, display):
1412
+ return
1413
+
1414
+ self._xpos, self._ypos = x, y
1415
+
1416
+ self.ResetControlPoints()
1417
+
1418
+ if display:
1419
+ self.Draw(dc)
1420
+
1421
+ self.MoveLinks(dc)
1422
+
1423
+ self.GetEventHandler().OnMovePost(dc, x, y, old_x, old_y, display)
1424
+
1425
+ def MoveLinks(self, dc):
1426
+ """Redraw all the lines attached to the shape."""
1427
+ self.GetEventHandler().OnMoveLinks(dc)
1428
+
1429
+ def Draw(self, dc):
1430
+ """
1431
+ Draw the whole shape and any lines attached to it.
1432
+
1433
+ Do not override this function: override OnDraw, which is called
1434
+ by this function.
1435
+ """
1436
+ if self._visible:
1437
+ self.GetEventHandler().OnDraw(dc)
1438
+ self.GetEventHandler().OnDrawContents(dc)
1439
+ self.GetEventHandler().OnDrawControlPoints(dc)
1440
+ self.GetEventHandler().OnDrawBranches(dc)
1441
+
1442
+ def Flash(self):
1443
+ """Flash the shape."""
1444
+ if self.GetCanvas():
1445
+ dc = wx.MemoryDC()
1446
+ dc.SelectObject(self.GetCanvas().GetBuffer())
1447
+ self.GetCanvas().PrepareDC(dc)
1448
+ dc.SetLogicalFunction(OGLRBLF)
1449
+ self.Draw(dc)
1450
+ dc.SetLogicalFunction(wx.COPY)
1451
+ self.Draw(dc)
1452
+
1453
+ def Show(self, show):
1454
+ """Set a flag indicating whether the shape should be drawn."""
1455
+ self._visible = show
1456
+ for child in self._children:
1457
+ child.Show(show)
1458
+
1459
+ def Erase(self, dc):
1460
+ """
1461
+ Erase the shape.
1462
+
1463
+ Does not repair damage caused to other shapes.
1464
+ """
1465
+ self.GetEventHandler().OnErase(dc)
1466
+ self.GetEventHandler().OnEraseControlPoints(dc)
1467
+ self.GetEventHandler().OnDrawBranches(dc, erase = True)
1468
+
1469
+ def EraseContents(self, dc):
1470
+ """
1471
+ Erase the shape contents, that is, the area within the shape's
1472
+ minimum bounding box.
1473
+ """
1474
+ self.GetEventHandler().OnEraseContents(dc)
1475
+
1476
+ def AddText(self, string):
1477
+ """Add a line of text to the shape's default text region."""
1478
+ if not self._regions:
1479
+ return
1480
+
1481
+ region = self._regions[0]
1482
+ #region.ClearText()
1483
+ new_line = ShapeTextLine(0, 0, string)
1484
+ text = region.GetFormattedText()
1485
+ text.append(new_line)
1486
+
1487
+ self._formatted = False
1488
+
1489
+ def SetSize(self, x, y, recursive = True):
1490
+ """Set the shape's size.
1491
+
1492
+ :param `x`: the x position
1493
+ :param `y`: the y position
1494
+ :param `recursive`: not used
1495
+
1496
+ """
1497
+ self.SetAttachmentSize(x, y)
1498
+ self.SetDefaultRegionSize()
1499
+
1500
+ def SetAttachmentSize(self, w, h):
1501
+ """
1502
+ Set the attachment size.
1503
+
1504
+ :param `w`: width
1505
+ :param `h`: height
1506
+
1507
+ """
1508
+ width, height = self.GetBoundingBoxMin()
1509
+ if width == 0:
1510
+ scaleX = 1.0
1511
+ else:
1512
+ scaleX = float(w) / width
1513
+ if height == 0:
1514
+ scaleY = 1.0
1515
+ else:
1516
+ scaleY = float(h) / height
1517
+
1518
+ for point in self._attachmentPoints:
1519
+ point._x = point._x * scaleX
1520
+ point._y = point._y * scaleY
1521
+
1522
+ # Add line FROM this object
1523
+ def AddLine(self, line, other, attachFrom = 0, attachTo = 0, positionFrom = -1, positionTo = -1):
1524
+ """
1525
+ Add a line between this shape and the given other shape, at the
1526
+ specified attachment points.
1527
+
1528
+ :param `line`: the line an instance of :class:`~lib.ogl.LineShape`
1529
+ :param `other`: the other shape, an instance of :class:`Shape`
1530
+ :param `attachFrom`: the attachment from point ???
1531
+ :param `attachTo`: the attachment to point ???
1532
+ :param `positionFrom`: the from position
1533
+ :param `positionTo`: the to position
1534
+
1535
+ :note: The position in the list of lines at each end can also be
1536
+ specified, so that the line will be drawn at a particular point on
1537
+ its attachment point.
1538
+
1539
+ """
1540
+ if positionFrom == -1:
1541
+ if not line in self._lines:
1542
+ self._lines.append(line)
1543
+ else:
1544
+ # Don't preserve old ordering if we have new ordering instructions
1545
+ try:
1546
+ self._lines.remove(line)
1547
+ except ValueError:
1548
+ pass
1549
+ if positionFrom < len(self._lines):
1550
+ self._lines.insert(positionFrom, line)
1551
+ else:
1552
+ self._lines.append(line)
1553
+
1554
+ if positionTo == -1:
1555
+ if not other in other._lines:
1556
+ other._lines.append(line)
1557
+ else:
1558
+ # Don't preserve old ordering if we have new ordering instructions
1559
+ try:
1560
+ other._lines.remove(line)
1561
+ except ValueError:
1562
+ pass
1563
+ if positionTo < len(other._lines):
1564
+ other._lines.insert(positionTo, line)
1565
+ else:
1566
+ other._lines.append(line)
1567
+
1568
+ line.SetFrom(self)
1569
+ line.SetTo(other)
1570
+ line.SetAttachments(attachFrom, attachTo)
1571
+
1572
+ dc = wx.MemoryDC()
1573
+ dc.SelectObject(self.GetCanvas().GetBuffer())
1574
+ self.GetCanvas().PrepareDC(dc)
1575
+ self.MoveLinks(dc)
1576
+
1577
+ def RemoveLine(self, line):
1578
+ """
1579
+ Remove the given line from the shape's list of attached lines.
1580
+
1581
+ :param `line`: an instance of :class:`~lib.ogl.LineShape`
1582
+
1583
+ """
1584
+ if line.GetFrom() == self:
1585
+ line.GetTo()._lines.remove(line)
1586
+ else:
1587
+ line.GetFrom()._lines.remove(line)
1588
+
1589
+ self._lines.remove(line)
1590
+
1591
+ # Default - make 6 control points
1592
+ def MakeControlPoints(self):
1593
+ """
1594
+ Make a list of control points (draggable handles) appropriate to
1595
+ the shape.
1596
+ """
1597
+ maxX, maxY = self.GetBoundingBoxMax()
1598
+ minX, minY = self.GetBoundingBoxMin()
1599
+
1600
+ widthMin = minX + CONTROL_POINT_SIZE + 2
1601
+ heightMin = minY + CONTROL_POINT_SIZE + 2
1602
+
1603
+ # Offsets from main object
1604
+ top = -heightMin / 2.0
1605
+ bottom = heightMin / 2.0 + (maxY - minY)
1606
+ left = -widthMin / 2.0
1607
+ right = widthMin / 2.0 + (maxX - minX)
1608
+
1609
+ control = ControlPoint(self._canvas, self, CONTROL_POINT_SIZE, left, top, CONTROL_POINT_DIAGONAL)
1610
+ self._canvas.AddShape(control)
1611
+ self._controlPoints.append(control)
1612
+
1613
+ control = ControlPoint(self._canvas, self, CONTROL_POINT_SIZE, 0, top, CONTROL_POINT_VERTICAL)
1614
+ self._canvas.AddShape(control)
1615
+ self._controlPoints.append(control)
1616
+
1617
+ control = ControlPoint(self._canvas, self, CONTROL_POINT_SIZE, right, top, CONTROL_POINT_DIAGONAL)
1618
+ self._canvas.AddShape(control)
1619
+ self._controlPoints.append(control)
1620
+
1621
+ control = ControlPoint(self._canvas, self, CONTROL_POINT_SIZE, right, 0, CONTROL_POINT_HORIZONTAL)
1622
+ self._canvas.AddShape(control)
1623
+ self._controlPoints.append(control)
1624
+
1625
+ control = ControlPoint(self._canvas, self, CONTROL_POINT_SIZE, right, bottom, CONTROL_POINT_DIAGONAL)
1626
+ self._canvas.AddShape(control)
1627
+ self._controlPoints.append(control)
1628
+
1629
+ control = ControlPoint(self._canvas, self, CONTROL_POINT_SIZE, 0, bottom, CONTROL_POINT_VERTICAL)
1630
+ self._canvas.AddShape(control)
1631
+ self._controlPoints.append(control)
1632
+
1633
+ control = ControlPoint(self._canvas, self, CONTROL_POINT_SIZE, left, bottom, CONTROL_POINT_DIAGONAL)
1634
+ self._canvas.AddShape(control)
1635
+ self._controlPoints.append(control)
1636
+
1637
+ control = ControlPoint(self._canvas, self, CONTROL_POINT_SIZE, left, 0, CONTROL_POINT_HORIZONTAL)
1638
+ self._canvas.AddShape(control)
1639
+ self._controlPoints.append(control)
1640
+
1641
+ def MakeMandatoryControlPoints(self):
1642
+ """
1643
+ Make the mandatory control points.
1644
+
1645
+ For example, the control point on a dividing line should appear even
1646
+ if the divided rectangle shape's handles should not appear (because
1647
+ it is the child of a composite, and children are not resizable).
1648
+ """
1649
+ for child in self._children:
1650
+ child.MakeMandatoryControlPoints()
1651
+
1652
+ def ResetMandatoryControlPoints(self):
1653
+ """Reset the mandatory control points."""
1654
+ for child in self._children:
1655
+ child.ResetMandatoryControlPoints()
1656
+
1657
+ def ResetControlPoints(self):
1658
+ """
1659
+ Reset the positions of the control points (for instance when the
1660
+ shape's shape has changed).
1661
+ """
1662
+ self.ResetMandatoryControlPoints()
1663
+
1664
+ if len(self._controlPoints) == 0:
1665
+ return
1666
+
1667
+ maxX, maxY = self.GetBoundingBoxMax()
1668
+ minX, minY = self.GetBoundingBoxMin()
1669
+
1670
+ widthMin = minX + CONTROL_POINT_SIZE + 2
1671
+ heightMin = minY + CONTROL_POINT_SIZE + 2
1672
+
1673
+ # Offsets from main object
1674
+ top = -heightMin / 2.0
1675
+ bottom = heightMin / 2.0 + (maxY - minY)
1676
+ left = -widthMin / 2.0
1677
+ right = widthMin / 2.0 + (maxX - minX)
1678
+
1679
+ self._controlPoints[0]._xoffset = left
1680
+ self._controlPoints[0]._yoffset = top
1681
+
1682
+ self._controlPoints[1]._xoffset = 0
1683
+ self._controlPoints[1]._yoffset = top
1684
+
1685
+ self._controlPoints[2]._xoffset = right
1686
+ self._controlPoints[2]._yoffset = top
1687
+
1688
+ self._controlPoints[3]._xoffset = right
1689
+ self._controlPoints[3]._yoffset = 0
1690
+
1691
+ self._controlPoints[4]._xoffset = right
1692
+ self._controlPoints[4]._yoffset = bottom
1693
+
1694
+ self._controlPoints[5]._xoffset = 0
1695
+ self._controlPoints[5]._yoffset = bottom
1696
+
1697
+ self._controlPoints[6]._xoffset = left
1698
+ self._controlPoints[6]._yoffset = bottom
1699
+
1700
+ self._controlPoints[7]._xoffset = left
1701
+ self._controlPoints[7]._yoffset = 0
1702
+
1703
+ def DeleteControlPoints(self, dc = None):
1704
+ """
1705
+ Delete the control points (or handles) for the shape.
1706
+
1707
+ Does not redraw the shape.
1708
+ """
1709
+ for control in self._controlPoints[:]:
1710
+ if dc:
1711
+ control.GetEventHandler().OnErase(dc)
1712
+ control.Delete()
1713
+ self._controlPoints.remove(control)
1714
+ self._controlPoints = []
1715
+
1716
+ # Children of divisions are contained objects,
1717
+ # so stop here
1718
+ if not isinstance(self, DivisionShape):
1719
+ for child in self._children:
1720
+ child.DeleteControlPoints(dc)
1721
+
1722
+ def OnDrawControlPoints(self, dc):
1723
+ """The draw control points handler."""
1724
+ if not self._drawHandles:
1725
+ return
1726
+
1727
+ dc.SetBrush(wx.BLACK_BRUSH)
1728
+ dc.SetPen(wx.BLACK_PEN)
1729
+
1730
+ for control in self._controlPoints:
1731
+ control.Draw(dc)
1732
+
1733
+ # Children of divisions are contained objects,
1734
+ # so stop here.
1735
+ # This test bypasses the type facility for speed
1736
+ # (critical when drawing)
1737
+
1738
+ if not isinstance(self, DivisionShape):
1739
+ for child in self._children:
1740
+ child.GetEventHandler().OnDrawControlPoints(dc)
1741
+
1742
+ def OnEraseControlPoints(self, dc):
1743
+ """The erase control points handler."""
1744
+ for control in self._controlPoints:
1745
+ control.Erase(dc)
1746
+
1747
+ if not isinstance(self, DivisionShape):
1748
+ for child in self._children:
1749
+ child.GetEventHandler().OnEraseControlPoints(dc)
1750
+
1751
+ def Select(self, select, dc = None):
1752
+ """
1753
+ Select or deselect the given shape, drawing or erasing control points
1754
+ (handles) as necessary.
1755
+
1756
+ :param `select`: `True` to select
1757
+ :param `dc`: the device context
1758
+
1759
+ """
1760
+ self._selected = select
1761
+ if select:
1762
+ self.MakeControlPoints()
1763
+ # Children of divisions are contained objects,
1764
+ # so stop here
1765
+ if not isinstance(self, DivisionShape):
1766
+ for child in self._children:
1767
+ child.MakeMandatoryControlPoints()
1768
+ if dc:
1769
+ self.GetEventHandler().OnDrawControlPoints(dc)
1770
+ else:
1771
+ self.DeleteControlPoints(dc)
1772
+ if not isinstance(self, DivisionShape):
1773
+ for child in self._children:
1774
+ child.DeleteControlPoints(dc)
1775
+
1776
+ def Selected(self):
1777
+ """`True` if the shape is currently selected."""
1778
+ return self._selected
1779
+
1780
+ def AncestorSelected(self):
1781
+ """`True` if the shape's ancestor is currently selected."""
1782
+ if self._selected:
1783
+ return True
1784
+ if not self.GetParent():
1785
+ return False
1786
+ return self.GetParent().AncestorSelected()
1787
+
1788
+ def GetNumberOfAttachments(self):
1789
+ """Get the number of attachment points for this shape."""
1790
+ # Should return the MAXIMUM attachment point id here,
1791
+ # so higher-level functions can iterate through all attachments,
1792
+ # even if they're not contiguous.
1793
+
1794
+ if len(self._attachmentPoints) == 0:
1795
+ return 4
1796
+ else:
1797
+ maxN = 3
1798
+ for point in self._attachmentPoints:
1799
+ if point._id > maxN:
1800
+ maxN = point._id
1801
+ return maxN + 1
1802
+
1803
+ def AttachmentIsValid(self, attachment):
1804
+ """`True` if attachment is a valid attachment point."""
1805
+ if len(self._attachmentPoints) == 0:
1806
+ return attachment in range(4)
1807
+
1808
+ for point in self._attachmentPoints:
1809
+ if point._id == attachment:
1810
+ return True
1811
+ return False
1812
+
1813
+ def GetAttachmentPosition(self, attachment, nth = 0, no_arcs = 1, line = None):
1814
+ """
1815
+ Get the position at which the given attachment point should be drawn.
1816
+
1817
+ :param `attachment`: the attachment ???
1818
+ :param `nth`: get nth attachment ???
1819
+ :param `no_arcs`: ???
1820
+ :param `line`: ???
1821
+
1822
+ If attachment isn't found among the attachment points of the shape,
1823
+ returns None.
1824
+ """
1825
+ if self._attachmentMode == ATTACHMENT_MODE_NONE:
1826
+ return self._xpos, self._ypos
1827
+ elif self._attachmentMode == ATTACHMENT_MODE_BRANCHING:
1828
+ pt, stemPt = self.GetBranchingAttachmentPoint(attachment, nth)
1829
+ return pt[0], pt[1]
1830
+ elif self._attachmentMode == ATTACHMENT_MODE_EDGE:
1831
+ if len(self._attachmentPoints):
1832
+ for point in self._attachmentPoints:
1833
+ if point._id == attachment:
1834
+ return self._xpos + point._x, self._ypos + point._y
1835
+ return None
1836
+ else:
1837
+ # Assume is rectangular
1838
+ w, h = self.GetBoundingBoxMax()
1839
+ top = self._ypos + h / 2.0
1840
+ bottom = self._ypos - h / 2.0
1841
+ left = self._xpos - w / 2.0
1842
+ right = self._xpos + w / 2.0
1843
+
1844
+ # wtf?
1845
+ line and line.IsEnd(self)
1846
+
1847
+ physicalAttachment = self.LogicalToPhysicalAttachment(attachment)
1848
+
1849
+ # Simplified code
1850
+ if physicalAttachment == 0:
1851
+ pt = self.CalcSimpleAttachment((left, bottom), (right, bottom), nth, no_arcs, line)
1852
+ elif physicalAttachment == 1:
1853
+ pt = self.CalcSimpleAttachment((right, bottom), (right, top), nth, no_arcs, line)
1854
+ elif physicalAttachment == 2:
1855
+ pt = self.CalcSimpleAttachment((left, top), (right, top), nth, no_arcs, line)
1856
+ elif physicalAttachment == 3:
1857
+ pt = self.CalcSimpleAttachment((left, bottom), (left, top), nth, no_arcs, line)
1858
+ else:
1859
+ return None
1860
+ return pt[0], pt[1]
1861
+ return None
1862
+
1863
+ def GetBoundingBoxMax(self):
1864
+ """
1865
+ Get the maximum bounding box for the shape, taking into account
1866
+ external features such as shadows.
1867
+ """
1868
+ ww, hh = self.GetBoundingBoxMin()
1869
+ if self._shadowMode != SHADOW_NONE:
1870
+ ww += self._shadowOffsetX
1871
+ hh += self._shadowOffsetY
1872
+ return ww, hh
1873
+
1874
+ def GetBoundingBoxMin(self):
1875
+ """
1876
+ Get the minimum bounding box for the shape, that defines the area
1877
+ available for drawing the contents (such as text).
1878
+
1879
+ Must be overridden.
1880
+ """
1881
+ return 0, 0
1882
+
1883
+ def HasDescendant(self, image):
1884
+ """
1885
+ Is image a descendant of this composite.
1886
+
1887
+ :param `image`: the image, is this a shape???
1888
+ :returns: `True` if it is a descendant
1889
+
1890
+ """
1891
+ if image == self:
1892
+ return True
1893
+ for child in self._children:
1894
+ if child.HasDescendant(image):
1895
+ return True
1896
+ return False
1897
+
1898
+ # Assuming the attachment lies along a vertical or horizontal line,
1899
+ # calculate the position on that point.
1900
+ def CalcSimpleAttachment(self, pt1, pt2, nth, noArcs, line):
1901
+ """
1902
+ Assuming the attachment lies along a vertical or horizontal line,
1903
+ calculate the position on that point.
1904
+
1905
+ :param `pt1`: The first point of the line repesenting the edge of
1906
+ the shape
1907
+ :param `pt2`: The second point of the line representing the edge of
1908
+ the shape
1909
+ :param `nth`: The position on the edge (for example there may be 6
1910
+ lines at this attachment point, and this may be the 2nd line.
1911
+ :param `noArcs`: The number of lines at this edge.
1912
+ :param `line`: The line shape.
1913
+
1914
+ :note: This function expects the line to be either vertical or horizontal,
1915
+ and determines which.
1916
+
1917
+ """
1918
+ isEnd = line and line.IsEnd(self)
1919
+
1920
+ # Are we horizontal or vertical?
1921
+ isHorizontal = RoughlyEqual(pt1[1], pt2[1])
1922
+
1923
+ if isHorizontal:
1924
+ if pt1[0] > pt2[0]:
1925
+ firstPoint = pt2
1926
+ secondPoint = pt1
1927
+ else:
1928
+ firstPoint = pt1
1929
+ secondPoint = pt2
1930
+
1931
+ if self._spaceAttachments:
1932
+ if line and line.GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE:
1933
+ # Align line according to the next handle along
1934
+ point = line.GetNextControlPoint(self)
1935
+ if point[0] < firstPoint[0]:
1936
+ x = firstPoint[0]
1937
+ elif point[0] > secondPoint[0]:
1938
+ x = secondPoint[0]
1939
+ else:
1940
+ x = point[0]
1941
+ else:
1942
+ x = firstPoint[0] + (nth + 1) * (secondPoint[0] - firstPoint[0]) / (noArcs + 1.0)
1943
+ else:
1944
+ x = (secondPoint[0] - firstPoint[0]) / 2.0 # Midpoint
1945
+ y = pt1[1]
1946
+ else:
1947
+ assert RoughlyEqual(pt1[0], pt2[0])
1948
+
1949
+ if pt1[1] > pt2[1]:
1950
+ firstPoint = pt2
1951
+ secondPoint = pt1
1952
+ else:
1953
+ firstPoint = pt1
1954
+ secondPoint = pt2
1955
+
1956
+ if self._spaceAttachments:
1957
+ if line and line.GetAlignmentType(isEnd) == LINE_ALIGNMENT_TO_NEXT_HANDLE:
1958
+ # Align line according to the next handle along
1959
+ point = line.GetNextControlPoint(self)
1960
+ if point[1] < firstPoint[1]:
1961
+ y = firstPoint[1]
1962
+ elif point[1] > secondPoint[1]:
1963
+ y = secondPoint[1]
1964
+ else:
1965
+ y = point[1]
1966
+ else:
1967
+ y = firstPoint[1] + (nth + 1) * (secondPoint[1] - firstPoint[1]) / (noArcs + 1.0)
1968
+ else:
1969
+ y = (secondPoint[1] - firstPoint[1]) / 2.0 # Midpoint
1970
+ x = pt1[0]
1971
+
1972
+ return x, y
1973
+
1974
+ def GetLinePosition(self, line):
1975
+ """
1976
+ Get the zero-based position of line in the list of lines
1977
+ for this shape.
1978
+
1979
+ :param `line`: line to find position for
1980
+
1981
+ """
1982
+ try:
1983
+ return self._lines.index(line)
1984
+ except:
1985
+ return 0
1986
+
1987
+
1988
+ # |________|
1989
+ # | <- root
1990
+ # | <- neck
1991
+ # shoulder1 ->---------<- shoulder2
1992
+ # | | | | |
1993
+ # <- branching attachment point N-1
1994
+
1995
+ def GetBranchingAttachmentInfo(self, attachment):
1996
+ """
1997
+ Get information about where branching connections go.
1998
+
1999
+ :param `attachment`: ???
2000
+ :returns: `False` if there are no lines at this attachment.
2001
+ """
2002
+ physicalAttachment = self.LogicalToPhysicalAttachment(attachment)
2003
+
2004
+ # Number of lines at this attachment
2005
+ lineCount = self.GetAttachmentLineCount(attachment)
2006
+
2007
+ if not lineCount:
2008
+ return False
2009
+
2010
+ totalBranchLength = self._branchSpacing * (lineCount - 1)
2011
+ root = self.GetBranchingAttachmentRoot(attachment)
2012
+
2013
+ neck = wx.RealPoint()
2014
+ shoulder1 = wx.RealPoint()
2015
+ shoulder2 = wx.RealPoint()
2016
+
2017
+ # Assume that we have attachment points 0 to 3: top, right, bottom, left
2018
+ if physicalAttachment == 0:
2019
+ neck[0] = self.GetX()
2020
+ neck[1] = root[1] - self._branchNeckLength
2021
+
2022
+ shoulder1[0] = root[0] - totalBranchLength / 2.0
2023
+ shoulder2[0] = root[0] + totalBranchLength / 2.0
2024
+
2025
+ shoulder1[1] = neck[1]
2026
+ shoulder2[1] = neck[1]
2027
+ elif physicalAttachment == 1:
2028
+ neck[0] = root[0] + self._branchNeckLength
2029
+ neck[1] = root[1]
2030
+
2031
+ shoulder1[0] = neck[0]
2032
+ shoulder2[0] = neck[0]
2033
+
2034
+ shoulder1[1] = neck[1] - totalBranchLength / 2.0
2035
+ shoulder1[1] = neck[1] + totalBranchLength / 2.0
2036
+ elif physicalAttachment == 2:
2037
+ neck[0] = self.GetX()
2038
+ neck[1] = root[1] + self._branchNeckLength
2039
+
2040
+ shoulder1[0] = root[0] - totalBranchLength / 2.0
2041
+ shoulder2[0] = root[0] + totalBranchLength / 2.0
2042
+
2043
+ shoulder1[1] = neck[1]
2044
+ shoulder2[1] = neck[1]
2045
+ elif physicalAttachment == 3:
2046
+ neck[0] = root[0] - self._branchNeckLength
2047
+ neck[1] = root[1]
2048
+
2049
+ shoulder1[0] = neck[0]
2050
+ shoulder2[0] = neck[0]
2051
+
2052
+ shoulder1[1] = neck[1] - totalBranchLength / 2.0
2053
+ shoulder2[1] = neck[1] + totalBranchLength / 2.0
2054
+ else:
2055
+ raise ValueError("Unrecognised attachment point in GetBranchingAttachmentInfo")
2056
+ return root, neck, shoulder1, shoulder2
2057
+
2058
+ def GetBranchingAttachmentPoint(self, attachment, n):
2059
+ """
2060
+ Get branching attachment point.
2061
+
2062
+ :param `attachment`: ???
2063
+ :param `n`: ???
2064
+
2065
+ """
2066
+ physicalAttachment = self.LogicalToPhysicalAttachment(attachment)
2067
+
2068
+ root, neck, shoulder1, shoulder2 = self.GetBranchingAttachmentInfo(attachment)
2069
+ pt = wx.RealPoint()
2070
+ stemPt = wx.RealPoint()
2071
+
2072
+ if physicalAttachment == 0:
2073
+ pt[1] = neck[1] - self._branchStemLength
2074
+ pt[0] = shoulder1[0] + n * self._branchSpacing
2075
+
2076
+ stemPt[0] = pt[0]
2077
+ stemPt[1] = neck[1]
2078
+ elif physicalAttachment == 2:
2079
+ pt[1] = neck[1] + self._branchStemLength
2080
+ pt[0] = shoulder1[0] + n * self._branchStemLength
2081
+
2082
+ stemPt[0] = pt[0]
2083
+ stemPt[1] = neck[1]
2084
+ elif physicalAttachment == 1:
2085
+ pt[0] = neck[0] + self._branchStemLength
2086
+ pt[1] = shoulder1[1] + n * self._branchSpacing
2087
+
2088
+ stemPt[0] = neck[0]
2089
+ stemPt[1] = pt[1]
2090
+ elif physicalAttachment == 3:
2091
+ pt[0] = neck[0] - self._branchStemLength
2092
+ pt[1] = shoulder1[1] + n * self._branchSpacing
2093
+
2094
+ stemPt[0] = neck[0]
2095
+ stemPt[1] = pt[1]
2096
+ else:
2097
+ raise ValueError("Unrecognised attachment point in GetBranchingAttachmentPoint")
2098
+
2099
+ return pt, stemPt
2100
+
2101
+ def GetAttachmentLineCount(self, attachment):
2102
+ """
2103
+ Get the number of lines at this attachment position.
2104
+
2105
+ :param `attachment`: ???
2106
+ :returns: the count of lines at this position
2107
+
2108
+ """
2109
+ count = 0
2110
+ for lineShape in self._lines:
2111
+ if lineShape.GetFrom() == self and lineShape.GetAttachmentFrom() == attachment:
2112
+ count += 1
2113
+ elif lineShape.GetTo() == self and lineShape.GetAttachmentTo() == attachment:
2114
+ count += 1
2115
+ return count
2116
+
2117
+ def GetBranchingAttachmentRoot(self, attachment):
2118
+ """
2119
+ Get the root point at the given attachment.
2120
+
2121
+ :param `attachment`: ???
2122
+
2123
+ """
2124
+ physicalAttachment = self.LogicalToPhysicalAttachment(attachment)
2125
+
2126
+ root = wx.RealPoint()
2127
+
2128
+ width, height = self.GetBoundingBoxMax()
2129
+
2130
+ # Assume that we have attachment points 0 to 3: top, right, bottom, left
2131
+ if physicalAttachment == 0:
2132
+ root[0] = self.GetX()
2133
+ root[1] = self.GetY() - height / 2.0
2134
+ elif physicalAttachment == 1:
2135
+ root[0] = self.GetX() + width / 2.0
2136
+ root[1] = self.GetY()
2137
+ elif physicalAttachment == 2:
2138
+ root[0] = self.GetX()
2139
+ root[1] = self.GetY() + height / 2.0
2140
+ elif physicalAttachment == 3:
2141
+ root[0] = self.GetX() - width / 2.0
2142
+ root[1] = self.GetY()
2143
+ else:
2144
+ raise ValueError("Unrecognised attachment point in GetBranchingAttachmentRoot")
2145
+
2146
+ return root
2147
+
2148
+ # Draw or erase the branches (not the actual arcs though)
2149
+ def OnDrawBranchesAttachment(self, dc, attachment, erase = False):
2150
+ """The draw branches attachment handler."""
2151
+ count = self.GetAttachmentLineCount(attachment)
2152
+ if count == 0:
2153
+ return
2154
+
2155
+ root, neck, shoulder1, shoulder2 = self.GetBranchingAttachmentInfo(attachment)
2156
+
2157
+ if erase:
2158
+ dc.SetPen(wx.WHITE_PEN)
2159
+ dc.SetBrush(wx.WHITE_BRUSH)
2160
+ else:
2161
+ dc.SetPen(wx.BLACK_PEN)
2162
+ dc.SetBrush(wx.BLACK_BRUSH)
2163
+
2164
+ # Draw neck
2165
+ dc.DrawLine(root[0], root[1], neck[0], neck[1])
2166
+
2167
+ if count > 1:
2168
+ # Draw shoulder-to-shoulder line
2169
+ dc.DrawLine(shoulder1[0], shoulder1[1], shoulder2[0], shoulder2[1])
2170
+ # Draw all the little branches
2171
+ for i in range(count):
2172
+ pt, stemPt = self.GetBranchingAttachmentPoint(attachment, i)
2173
+ dc.DrawLine(stemPt[0], stemPt[1], pt[0], pt[1])
2174
+
2175
+ if self.GetBranchStyle() & BRANCHING_ATTACHMENT_BLOB and count > 1:
2176
+ blobSize = 6.0
2177
+ dc.DrawEllipse(stemPt[0] - blobSize / 2.0, stemPt[1] - blobSize / 2.0, blobSize, blobSize)
2178
+
2179
+ def OnDrawBranches(self, dc, erase = False):
2180
+ """The draw branches handler."""
2181
+ if self._attachmentMode != ATTACHMENT_MODE_BRANCHING:
2182
+ return
2183
+ for i in range(self.GetNumberOfAttachments()):
2184
+ self.OnDrawBranchesAttachment(dc, i, erase)
2185
+
2186
+ def GetAttachmentPositionEdge(self, attachment, nth = 0, no_arcs = 1, line = None):
2187
+ """
2188
+ Only get the attachment position at the _edge_ of the shape,
2189
+ ignoring branching mode. This is used e.g. to indicate the edge of
2190
+ interest, not the point on the attachment branch.
2191
+
2192
+ :param `attachment`: the attachment ???
2193
+ :param `nth`: get nth attachment ???
2194
+ :param `no_arcs`: ???
2195
+ :param `line`: ???
2196
+
2197
+ """
2198
+ oldMode = self._attachmentMode
2199
+
2200
+ # Calculate as if to edge, not branch
2201
+ if self._attachmentMode == ATTACHMENT_MODE_BRANCHING:
2202
+ self._attachmentMode = ATTACHMENT_MODE_EDGE
2203
+ res = self.GetAttachmentPosition(attachment, nth, no_arcs, line)
2204
+ self._attachmentMode = oldMode
2205
+
2206
+ return res
2207
+
2208
+ def PhysicalToLogicalAttachment(self, physicalAttachment):
2209
+ """
2210
+ Rotate the standard attachment point from physical
2211
+ (0 is always North) to logical (0 -> 1 if rotated by 90 degrees)
2212
+
2213
+ :param `physicalAttachment`: ???
2214
+
2215
+ """
2216
+ if RoughlyEqual(self.GetRotation(), 0):
2217
+ i = physicalAttachment
2218
+ elif RoughlyEqual(self.GetRotation(), math.pi / 2.0):
2219
+ i = physicalAttachment - 1
2220
+ elif RoughlyEqual(self.GetRotation(), math.pi):
2221
+ i = physicalAttachment - 2
2222
+ elif RoughlyEqual(self.GetRotation(), 3 * math.pi / 2.0):
2223
+ i = physicalAttachment - 3
2224
+ else:
2225
+ # Can't handle -- assume the same
2226
+ return physicalAttachment
2227
+
2228
+ if i < 0:
2229
+ i += 4
2230
+
2231
+ return i
2232
+
2233
+ def LogicalToPhysicalAttachment(self, logicalAttachment):
2234
+ """
2235
+ Rotate the standard attachment point from logical
2236
+ to physical (0 is always North).
2237
+
2238
+ :param `logicalAttachment`: ???
2239
+
2240
+ """
2241
+ if RoughlyEqual(self.GetRotation(), 0):
2242
+ i = logicalAttachment
2243
+ elif RoughlyEqual(self.GetRotation(), math.pi / 2.0):
2244
+ i = logicalAttachment + 1
2245
+ elif RoughlyEqual(self.GetRotation(), math.pi):
2246
+ i = logicalAttachment + 2
2247
+ elif RoughlyEqual(self.GetRotation(), 3 * math.pi / 2.0):
2248
+ i = logicalAttachment + 3
2249
+ else:
2250
+ return logicalAttachment
2251
+
2252
+ if i > 3:
2253
+ i -= 4
2254
+
2255
+ return i
2256
+
2257
+ def Rotate(self, x, y, theta):
2258
+ """
2259
+ Rotate about the given axis by the given amount in radians.
2260
+
2261
+ :param `x`: the x position
2262
+ :param `y`: the y position
2263
+ :param `theta`: the theta
2264
+
2265
+ """
2266
+ self._rotation = theta
2267
+ if self._rotation < 0:
2268
+ self._rotation += 2 * math.pi
2269
+ elif self._rotation > 2 * math.pi:
2270
+ self._rotation -= 2 * math.pi
2271
+
2272
+ def GetBackgroundPen(self):
2273
+ """Return pen of the right colour for the background."""
2274
+ if self.GetCanvas():
2275
+ return wx.Pen(self.GetCanvas().GetBackgroundColour(), 1, wx.PENSTYLE_SOLID)
2276
+ return WhiteBackgroundPen
2277
+
2278
+ def GetBackgroundBrush(self):
2279
+ """Return brush of the right colour for the background."""
2280
+ if self.GetCanvas():
2281
+ return wx.Brush(self.GetCanvas().GetBackgroundColour(), wx.BRUSHSTYLE_SOLID)
2282
+ return WhiteBackgroundBrush
2283
+
2284
+ def GetX(self):
2285
+ """Get the x position of the centre of the shape."""
2286
+ return self._xpos
2287
+
2288
+ def GetY(self):
2289
+ """Get the y position of the centre of the shape."""
2290
+ return self._ypos
2291
+
2292
+ def SetX(self, x):
2293
+ """
2294
+ Set the x position of the shape.
2295
+
2296
+ :param `x`: the x position
2297
+ """
2298
+ self._xpos = x
2299
+
2300
+ def SetY(self, y):
2301
+ """
2302
+ Set the y position of the shape.
2303
+
2304
+ :param `y`: the y position
2305
+
2306
+ """
2307
+ self._ypos = y
2308
+
2309
+ def GetParent(self):
2310
+ """Get the parent of this shape, if it is part of a composite."""
2311
+ return self._parent
2312
+
2313
+ def SetParent(self, p):
2314
+ """Set the parent
2315
+
2316
+ :param `p`: the parent
2317
+
2318
+ """
2319
+ self._parent = p
2320
+
2321
+ def GetChildren(self):
2322
+ """Get the list of children for this shape."""
2323
+ return self._children
2324
+
2325
+ def GetDrawHandles(self):
2326
+ """Get the list of drawhandles."""
2327
+ return self._drawHandles
2328
+
2329
+ def GetEventHandler(self):
2330
+ """Get the event handler for this shape."""
2331
+ return self._eventHandler
2332
+
2333
+ def SetEventHandler(self, handler):
2334
+ """Set the event handler for this shape.
2335
+
2336
+ :param `handler`: an instance of :class:`ShapeEvtHandler`
2337
+
2338
+ """
2339
+ self._eventHandler = handler
2340
+
2341
+ def Recompute(self):
2342
+ """
2343
+ Recomputes any constraints associated with the shape.
2344
+
2345
+ Normally applicable to CompositeShapes only, but harmless for
2346
+ other classes of Shape.
2347
+ """
2348
+ return True
2349
+
2350
+ def IsHighlighted(self):
2351
+ """
2352
+ `True` if the shape is highlighted. Shape highlighting is unimplemented.
2353
+ """
2354
+ return self._highlighted
2355
+
2356
+ def GetSensitivityFilter(self):
2357
+ """
2358
+ Get the sensitivity filter, a bitlist of values.
2359
+
2360
+ See :meth:`Shape.SetSensitivityFilter`
2361
+
2362
+ """
2363
+ return self._sensitivity
2364
+
2365
+ def SetFixedSize(self, x, y):
2366
+ """
2367
+ Set the shape to be fixed size.
2368
+
2369
+ :param `x`: the width
2370
+ :param `y`: the height
2371
+
2372
+ """
2373
+ self._fixedWidth = x
2374
+ self._fixedHeight = y
2375
+
2376
+ def GetFixedSize(self):
2377
+ """
2378
+ Return flags indicating whether the shape is of fixed size in
2379
+ either direction.
2380
+ """
2381
+ return self._fixedWidth, self._fixedHeight
2382
+
2383
+ def GetFixedWidth(self):
2384
+ """`True` if the shape cannot be resized in the horizontal plane."""
2385
+ return self._fixedWidth
2386
+
2387
+ def GetFixedHeight(self):
2388
+ """`True` if the shape cannot be resized in the vertical plane."""
2389
+ return self._fixedHeight
2390
+
2391
+ def SetSpaceAttachments(self, sp):
2392
+ """
2393
+ Indicate whether lines should be spaced out evenly at the point
2394
+ they touch the node.
2395
+
2396
+ :param `sp`: if `True` space out evently, else they should join at a
2397
+ single point.
2398
+
2399
+ """
2400
+ self._spaceAttachments = sp
2401
+
2402
+ def GetSpaceAttachments(self):
2403
+ """
2404
+ Get whether lines should be spaced out evenly at the point they
2405
+ touch the node (True), or whether they should join at a single point
2406
+ (False).
2407
+ """
2408
+ return self._spaceAttachments
2409
+
2410
+ def SetCentreResize(self, cr):
2411
+ """
2412
+ Specify whether the shape is to be resized from the centre (the
2413
+ centre stands still) or from the corner or side being dragged (the
2414
+ other corner or side stands still).
2415
+ """
2416
+ self._centreResize = cr
2417
+
2418
+ def GetCentreResize(self):
2419
+ """
2420
+ `True` if the shape is to be resized from the centre (the centre stands
2421
+ still), or `False` if from the corner or side being dragged (the other
2422
+ corner or side stands still)
2423
+
2424
+ """
2425
+ return self._centreResize
2426
+
2427
+ def SetMaintainAspectRatio(self, ar):
2428
+ """
2429
+ Set whether a shape that resizes should not change the aspect ratio
2430
+ (width and height should be in the original proportion).
2431
+
2432
+ """
2433
+ self._maintainAspectRatio = ar
2434
+
2435
+ def GetMaintainAspectRatio(self):
2436
+ """`True` if shape keeps aspect ratio during resize."""
2437
+ return self._maintainAspectRatio
2438
+
2439
+ def GetLines(self):
2440
+ """Return the list of lines connected to this shape."""
2441
+ return self._lines
2442
+
2443
+ def SetDisableLabel(self, flag):
2444
+ """Set flag to `True` to stop the default region being shown."""
2445
+ self._disableLabel = flag
2446
+
2447
+ def GetDisableLabel(self):
2448
+ """`True` if the default region will not be shown, `False` otherwise."""
2449
+ return self._disableLabel
2450
+
2451
+ def SetAttachmentMode(self, mode):
2452
+ """
2453
+ Set the attachment mode.
2454
+
2455
+ :param `mode`: if `True` attachment points will be significant when
2456
+ drawing lines to and from this shape. If `False` lines will be drawn
2457
+ as if to the centre of the shape.
2458
+
2459
+ """
2460
+ self._attachmentMode = mode
2461
+
2462
+ def GetAttachmentMode(self):
2463
+ """
2464
+ Get the attachment mode.
2465
+
2466
+ See :meth:`Shape.SetAttachmentMode`
2467
+ """
2468
+ return self._attachmentMode
2469
+
2470
+ def SetId(self, i):
2471
+ """Set the integer identifier for this shape."""
2472
+ self._id = i
2473
+
2474
+ def GetId(self):
2475
+ """Get the integer identifier for this shape."""
2476
+ return self._id
2477
+
2478
+ def IsShown(self):
2479
+ """
2480
+ `True` if the shape is in a visible state, `False` otherwise.
2481
+
2482
+ :note: That this has nothing to do with whether the window is hidden
2483
+ or the shape has scrolled off the canvas; it refers to the internal
2484
+ visibility flag.
2485
+
2486
+ """
2487
+ return self._visible
2488
+
2489
+ def GetPen(self):
2490
+ """Get the pen used for drawing the shape's outline."""
2491
+ return self._pen
2492
+
2493
+ def GetBrush(self):
2494
+ """Get the brush used for filling the shape."""
2495
+ return self._brush
2496
+
2497
+ def GetNumberOfTextRegions(self):
2498
+ """Get the number of text regions for this shape."""
2499
+ return len(self._regions)
2500
+
2501
+ def GetRegions(self):
2502
+ """Get the list of ShapeRegions."""
2503
+ return self._regions
2504
+
2505
+ # Control points ('handles') redirect control to the actual shape, to
2506
+ # make it easier to override sizing behaviour.
2507
+ def OnSizingDragLeft(self, pt, draw, x, y, keys = 0, attachment = 0):
2508
+ """The sizing drag left handler."""
2509
+ bound_x, bound_y = self.GetBoundingBoxMin()
2510
+
2511
+ dc = wx.MemoryDC()
2512
+ dc.SelectObject(self.GetCanvas().GetBuffer())
2513
+ self.GetCanvas().PrepareDC(dc)
2514
+ dc.SetLogicalFunction(OGLRBLF)
2515
+
2516
+ dottedPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)
2517
+ dc.SetPen(dottedPen)
2518
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
2519
+
2520
+ if self.GetCentreResize():
2521
+ # Maintain the same centre point
2522
+ new_width = 2.0 * abs(x - self.GetX())
2523
+ new_height = 2.0 * abs(y - self.GetY())
2524
+
2525
+ # Constrain sizing according to what control point you're dragging
2526
+ if pt._type == CONTROL_POINT_HORIZONTAL:
2527
+ if self.GetMaintainAspectRatio():
2528
+ new_height = bound_y * (new_width / bound_x)
2529
+ else:
2530
+ new_height = bound_y
2531
+ elif pt._type == CONTROL_POINT_VERTICAL:
2532
+ if self.GetMaintainAspectRatio():
2533
+ new_width = bound_x * (new_height / bound_y)
2534
+ else:
2535
+ new_width = bound_x
2536
+ elif pt._type == CONTROL_POINT_DIAGONAL and (keys & KEY_SHIFT):
2537
+ new_height = bound_y * (new_width / bound_x)
2538
+
2539
+ if self.GetFixedWidth():
2540
+ new_width = bound_x
2541
+
2542
+ if self.GetFixedHeight():
2543
+ new_height = bound_y
2544
+
2545
+ pt._controlPointDragEndWidth = new_width
2546
+ pt._controlPointDragEndHeight = new_height
2547
+
2548
+ self.GetEventHandler().OnDrawOutline(dc, self.GetX(), self.GetY(), new_width, new_height)
2549
+ else:
2550
+ # Don't maintain the same centre point
2551
+ newX1 = min(pt._controlPointDragStartX, x)
2552
+ newY1 = min(pt._controlPointDragStartY, y)
2553
+ newX2 = max(pt._controlPointDragStartX, x)
2554
+ newY2 = max(pt._controlPointDragStartY, y)
2555
+ if pt._type == CONTROL_POINT_HORIZONTAL:
2556
+ newY1 = pt._controlPointDragStartY
2557
+ newY2 = newY1 + pt._controlPointDragStartHeight
2558
+ elif pt._type == CONTROL_POINT_VERTICAL:
2559
+ newX1 = pt._controlPointDragStartX
2560
+ newX2 = newX1 + pt._controlPointDragStartWidth
2561
+ elif pt._type == CONTROL_POINT_DIAGONAL and (keys & KEY_SHIFT or self.GetMaintainAspectRatio()):
2562
+ newH = (newX2 - newX1) * (float(pt._controlPointDragStartHeight) / pt._controlPointDragStartWidth)
2563
+ if self.GetY() > pt._controlPointDragStartY:
2564
+ newY2 = newY1 + newH
2565
+ else:
2566
+ newY1 = newY2 - newH
2567
+
2568
+ newWidth = float(newX2 - newX1)
2569
+ newHeight = float(newY2 - newY1)
2570
+
2571
+ if pt._type == CONTROL_POINT_VERTICAL and self.GetMaintainAspectRatio():
2572
+ newWidth = bound_x * (newHeight / bound_y)
2573
+
2574
+ if pt._type == CONTROL_POINT_HORIZONTAL and self.GetMaintainAspectRatio():
2575
+ newHeight = bound_y * (newWidth / bound_x)
2576
+
2577
+ pt._controlPointDragPosX = newX1 + newWidth / 2.0
2578
+ pt._controlPointDragPosY = newY1 + newHeight / 2.0
2579
+ if self.GetFixedWidth():
2580
+ newWidth = bound_x
2581
+
2582
+ if self.GetFixedHeight():
2583
+ newHeight = bound_y
2584
+
2585
+ pt._controlPointDragEndWidth = newWidth
2586
+ pt._controlPointDragEndHeight = newHeight
2587
+ self.GetEventHandler().OnDrawOutline(dc, pt._controlPointDragPosX, pt._controlPointDragPosY, newWidth, newHeight)
2588
+
2589
+ def OnSizingBeginDragLeft(self, pt, x, y, keys = 0, attachment = 0):
2590
+ """The sizing begin drag left handler."""
2591
+ self._canvas.CaptureMouse()
2592
+
2593
+ dc = wx.MemoryDC()
2594
+ dc.SelectObject(self.GetCanvas().GetBuffer())
2595
+ self.GetCanvas().PrepareDC(dc)
2596
+ dc.SetLogicalFunction(OGLRBLF)
2597
+
2598
+ bound_x, bound_y = self.GetBoundingBoxMin()
2599
+ self.GetEventHandler().OnBeginSize(bound_x, bound_y)
2600
+
2601
+ # Choose the 'opposite corner' of the object as the stationary
2602
+ # point in case this is non-centring resizing.
2603
+ if pt.GetX() < self.GetX():
2604
+ pt._controlPointDragStartX = self.GetX() + bound_x / 2.0
2605
+ else:
2606
+ pt._controlPointDragStartX = self.GetX() - bound_x / 2.0
2607
+
2608
+ if pt.GetY() < self.GetY():
2609
+ pt._controlPointDragStartY = self.GetY() + bound_y / 2.0
2610
+ else:
2611
+ pt._controlPointDragStartY = self.GetY() - bound_y / 2.0
2612
+
2613
+ if pt._type == CONTROL_POINT_HORIZONTAL:
2614
+ pt._controlPointDragStartY = self.GetY() - bound_y / 2.0
2615
+ elif pt._type == CONTROL_POINT_VERTICAL:
2616
+ pt._controlPointDragStartX = self.GetX() - bound_x / 2.0
2617
+
2618
+ # We may require the old width and height
2619
+ pt._controlPointDragStartWidth = bound_x
2620
+ pt._controlPointDragStartHeight = bound_y
2621
+
2622
+ dottedPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)
2623
+ dc.SetPen(dottedPen)
2624
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
2625
+
2626
+ if self.GetCentreResize():
2627
+ new_width = 2.0 * abs(x - self.GetX())
2628
+ new_height = 2.0 * abs(y - self.GetY())
2629
+
2630
+ # Constrain sizing according to what control point you're dragging
2631
+ if pt._type == CONTROL_POINT_HORIZONTAL:
2632
+ if self.GetMaintainAspectRatio():
2633
+ new_height = bound_y * (new_width / bound_x)
2634
+ else:
2635
+ new_height = bound_y
2636
+ elif pt._type == CONTROL_POINT_VERTICAL:
2637
+ if self.GetMaintainAspectRatio():
2638
+ new_width = bound_x * (new_height / bound_y)
2639
+ else:
2640
+ new_width = bound_x
2641
+ elif pt._type == CONTROL_POINT_DIAGONAL and (keys & KEY_SHIFT):
2642
+ new_height = bound_y * (new_width / bound_x)
2643
+
2644
+ if self.GetFixedWidth():
2645
+ new_width = bound_x
2646
+
2647
+ if self.GetFixedHeight():
2648
+ new_height = bound_y
2649
+
2650
+ pt._controlPointDragEndWidth = new_width
2651
+ pt._controlPointDragEndHeight = new_height
2652
+ self.GetEventHandler().OnDrawOutline(dc, self.GetX(), self.GetY(), new_width, new_height)
2653
+ else:
2654
+ # Don't maintain the same centre point
2655
+ newX1 = min(pt._controlPointDragStartX, x)
2656
+ newY1 = min(pt._controlPointDragStartY, y)
2657
+ newX2 = max(pt._controlPointDragStartX, x)
2658
+ newY2 = max(pt._controlPointDragStartY, y)
2659
+ if pt._type == CONTROL_POINT_HORIZONTAL:
2660
+ newY1 = pt._controlPointDragStartY
2661
+ newY2 = newY1 + pt._controlPointDragStartHeight
2662
+ elif pt._type == CONTROL_POINT_VERTICAL:
2663
+ newX1 = pt._controlPointDragStartX
2664
+ newX2 = newX1 + pt._controlPointDragStartWidth
2665
+ elif pt._type == CONTROL_POINT_DIAGONAL and (keys & KEY_SHIFT or self.GetMaintainAspectRatio()):
2666
+ newH = (newX2 - newX1) * (float(pt._controlPointDragStartHeight) / pt._controlPointDragStartWidth)
2667
+ if pt.GetY() > pt._controlPointDragStartY:
2668
+ newY2 = newY1 + newH
2669
+ else:
2670
+ newY1 = newY2 - newH
2671
+
2672
+ newWidth = float(newX2 - newX1)
2673
+ newHeight = float(newY2 - newY1)
2674
+
2675
+ if pt._type == CONTROL_POINT_VERTICAL and self.GetMaintainAspectRatio():
2676
+ newWidth = bound_x * (newHeight / bound_y)
2677
+
2678
+ if pt._type == CONTROL_POINT_HORIZONTAL and self.GetMaintainAspectRatio():
2679
+ newHeight = bound_y * (newWidth / bound_x)
2680
+
2681
+ pt._controlPointDragPosX = newX1 + newWidth / 2.0
2682
+ pt._controlPointDragPosY = newY1 + newHeight / 2.0
2683
+ if self.GetFixedWidth():
2684
+ newWidth = bound_x
2685
+
2686
+ if self.GetFixedHeight():
2687
+ newHeight = bound_y
2688
+
2689
+ pt._controlPointDragEndWidth = newWidth
2690
+ pt._controlPointDragEndHeight = newHeight
2691
+ self.GetEventHandler().OnDrawOutline(dc, pt._controlPointDragPosX, pt._controlPointDragPosY, newWidth, newHeight)
2692
+
2693
+ def OnSizingEndDragLeft(self, pt, x, y, keys = 0, attachment = 0):
2694
+ """The sizing end drag left handler."""
2695
+ dc = wx.MemoryDC()
2696
+ dc.SelectObject(self.GetCanvas().GetBuffer())
2697
+ self.GetCanvas().PrepareDC(dc)
2698
+
2699
+ if self._canvas.HasCapture():
2700
+ self._canvas.ReleaseMouse()
2701
+ dc.SetLogicalFunction(wx.COPY)
2702
+ self.Recompute()
2703
+ self.ResetControlPoints()
2704
+
2705
+ self.Erase(dc)
2706
+
2707
+ self.SetSize(pt._controlPointDragEndWidth, pt._controlPointDragEndHeight)
2708
+
2709
+ # The next operation could destroy this control point (it does for
2710
+ # label objects, via formatting the text), so save all values we're
2711
+ # going to use, or we'll be accessing garbage.
2712
+
2713
+ #return
2714
+
2715
+ if self.GetCentreResize():
2716
+ self.Move(dc, self.GetX(), self.GetY())
2717
+ else:
2718
+ self.Move(dc, pt._controlPointDragPosX, pt._controlPointDragPosY)
2719
+
2720
+ # Recursively redraw links if we have a composite
2721
+ if len(self.GetChildren()):
2722
+ self.DrawLinks(dc, -1, True)
2723
+
2724
+ width, height = self.GetBoundingBoxMax()
2725
+ self.GetEventHandler().OnEndSize(width, height)
2726
+
2727
+ if not self._canvas.GetQuickEditMode() and pt._eraseObject:
2728
+ self._canvas.Redraw(dc)
2729
+
2730
+
2731
+ class RectangleShape(Shape):
2732
+ """
2733
+ The :class:`wx.RectangleShape` class has rounded or square corners.
2734
+ """
2735
+ def __init__(self, w = 0.0, h = 0.0):
2736
+ """
2737
+ Default class constructor
2738
+
2739
+ :param float `w`: the width
2740
+ :param float `h`: the height
2741
+
2742
+ """
2743
+ Shape.__init__(self)
2744
+ self._width = w
2745
+ self._height = h
2746
+ self._cornerRadius = 0.0
2747
+ self.SetDefaultRegionSize()
2748
+
2749
+ def OnDraw(self, dc):
2750
+ """The draw handler."""
2751
+ x1 = self._xpos - self._width / 2.0
2752
+ y1 = self._ypos - self._height / 2.0
2753
+
2754
+ if self._shadowMode != SHADOW_NONE:
2755
+ if self._shadowBrush:
2756
+ dc.SetBrush(self._shadowBrush)
2757
+ dc.SetPen(TransparentPen)
2758
+
2759
+ if self._cornerRadius:
2760
+ dc.DrawRoundedRectangle(*map(int, (x1 + self._shadowOffsetX, y1 + self._shadowOffsetY, self._width, self._height)), self._cornerRadius)
2761
+ else:
2762
+ dc.DrawRectangle(*map(int, (x1 + self._shadowOffsetX, y1 + self._shadowOffsetY, self._width, self._height)))
2763
+
2764
+ if self._pen:
2765
+ if self._pen.GetWidth() == 0:
2766
+ dc.SetPen(TransparentPen)
2767
+ else:
2768
+ dc.SetPen(self._pen)
2769
+ if self._brush:
2770
+ dc.SetBrush(self._brush)
2771
+
2772
+ if self._cornerRadius:
2773
+ dc.DrawRoundedRectangle(*map(int, (x1, y1, self._width, self._height)), self._cornerRadius)
2774
+ else:
2775
+ dc.DrawRectangle(*map(int, (x1, y1, self._width, self._height)))
2776
+
2777
+ def GetBoundingBoxMin(self):
2778
+ """Get the bounding box minimum."""
2779
+ return self._width, self._height
2780
+
2781
+ def SetSize(self, x, y, recursive = False):
2782
+ """
2783
+ Set the size.
2784
+
2785
+ :param `x`: the width
2786
+ :param `y`: the height
2787
+ :param `recursive`: not used
2788
+
2789
+ """
2790
+ self.SetAttachmentSize(x, y)
2791
+ self._width = max(x, 1)
2792
+ self._height = max(y, 1)
2793
+ self.SetDefaultRegionSize()
2794
+
2795
+ def GetCornerRadius(self):
2796
+ """Get the radius of the rectangle's rounded corners."""
2797
+ return self._cornerRadius
2798
+
2799
+ def SetCornerRadius(self, rad):
2800
+ """
2801
+ Set the radius of the rectangle's rounded corners.
2802
+
2803
+ :param `rad`: If the radius is zero, a non-rounded rectangle will be
2804
+ drawn. If the radius is negative, the value is the proportion of the
2805
+ smaller dimension of the rectangle.
2806
+
2807
+ """
2808
+ self._cornerRadius = rad
2809
+
2810
+ # Assume (x1, y1) is centre of box (most generally, line end at box)
2811
+ def GetPerimeterPoint(self, x1, y1, x2, y2):
2812
+ """
2813
+ Get the perimeter point.
2814
+
2815
+ :param `x1`: ???
2816
+ :param `y1`: ???
2817
+ :param `x2`: ???
2818
+ :param `y2`: ???
2819
+
2820
+ """
2821
+ bound_x, bound_y = self.GetBoundingBoxMax()
2822
+ return FindEndForBox(bound_x, bound_y, self._xpos, self._ypos, x2, y2)
2823
+
2824
+ def GetWidth(self):
2825
+ """Get the width."""
2826
+ return self._width
2827
+
2828
+ def GetHeight(self):
2829
+ """Get the height."""
2830
+ return self._height
2831
+
2832
+ def SetWidth(self, w):
2833
+ """
2834
+ Set the width.
2835
+
2836
+ :param `w`: width to be set
2837
+
2838
+ """
2839
+ self._width = w
2840
+
2841
+ def SetHeight(self, h):
2842
+ """
2843
+ Set the heigth.
2844
+
2845
+ :param `h`: heigth to be set
2846
+
2847
+ """
2848
+ self._height = h
2849
+
2850
+
2851
+ class PolygonShape(Shape):
2852
+ """
2853
+ The :class:`PolygonShape` class shape is defined by a number of points
2854
+ passed to the object's constructor. It can be used to create new shapes
2855
+ such as diamonds and triangles.
2856
+ """
2857
+ def __init__(self):
2858
+ """
2859
+ Default class constructor
2860
+
2861
+ Does not follow above statement, should it? or is Create called
2862
+ automagically?
2863
+
2864
+ """
2865
+ Shape.__init__(self)
2866
+
2867
+ self._points = None
2868
+ self._originalPoints = None
2869
+
2870
+ def Create(self, the_points = None):
2871
+ """
2872
+ Takes a list of :class:`wx.Points` or tuples; each point is an offset
2873
+ from the centre.
2874
+ """
2875
+ self.ClearPoints()
2876
+
2877
+ if not the_points:
2878
+ self._originalPoints = []
2879
+ self._points = []
2880
+ else:
2881
+ self._originalPoints = the_points
2882
+
2883
+ # Duplicate the list of points
2884
+ self._points = []
2885
+ for point in the_points:
2886
+ point = list(map(int, point))
2887
+ new_point = wx.Point(point[0], point[1])
2888
+ self._points.append(new_point)
2889
+ self.CalculateBoundingBox()
2890
+ self._originalWidth = self._boundWidth
2891
+ self._originalHeight = self._boundHeight
2892
+ self.SetDefaultRegionSize()
2893
+
2894
+ def ClearPoints(self):
2895
+ """Clear the points."""
2896
+ self._points = []
2897
+ self._originalPoints = []
2898
+
2899
+ # Width and height. Centre of object is centre of box
2900
+ def GetBoundingBoxMin(self):
2901
+ """Get minimum bounding box."""
2902
+ return self._boundWidth, self._boundHeight
2903
+
2904
+ def GetPoints(self):
2905
+ """Return the internal list of polygon vertices."""
2906
+ return self._points
2907
+
2908
+ def GetOriginalPoints(self):
2909
+ """Get the original points."""
2910
+ return self._originalPoints
2911
+
2912
+ def GetOriginalWidth(self):
2913
+ """Get the original width."""
2914
+ return self._originalWidth
2915
+
2916
+ def GetOriginalHeight(self):
2917
+ """Get the original height."""
2918
+ return self._originalHeight
2919
+
2920
+ def SetOriginalWidth(self, w):
2921
+ """
2922
+ Set the original width.
2923
+
2924
+ :param `w`: the width
2925
+
2926
+ """
2927
+ self._originalWidth = w
2928
+
2929
+ def SetOriginalHeight(self, h):
2930
+ """
2931
+ Set the original height.
2932
+
2933
+ :param `w`: the height
2934
+
2935
+ """
2936
+ self._originalHeight = h
2937
+
2938
+ def CalculateBoundingBox(self):
2939
+ """Calculate the bounding box."""
2940
+ left = 10000
2941
+ right = -10000
2942
+ top = 10000
2943
+ bottom = -10000
2944
+
2945
+ for point in self._points:
2946
+ if point[0] < left:
2947
+ left = point[0]
2948
+ if point[0] > right:
2949
+ right = point[0]
2950
+
2951
+ if point[1] < top:
2952
+ top = point[1]
2953
+ if point[1] > bottom:
2954
+ bottom = point[1]
2955
+
2956
+ self._boundWidth = right - left
2957
+ self._boundHeight = bottom - top
2958
+
2959
+ def CalculatePolygonCentre(self):
2960
+ """
2961
+ Recalculates the centre of the polygon, and
2962
+ readjusts the point offsets accordingly.
2963
+ Necessary since the centre of the polygon
2964
+ is expected to be the real centre of the bounding
2965
+ box.
2966
+ """
2967
+ left = 10000
2968
+ right = -10000
2969
+ top = 10000
2970
+ bottom = -10000
2971
+
2972
+ for point in self._points:
2973
+ if point[0] < left:
2974
+ left = point[0]
2975
+ if point[0] > right:
2976
+ right = point[0]
2977
+
2978
+ if point[1] < top:
2979
+ top = point[1]
2980
+ if point[1] > bottom:
2981
+ bottom = point[1]
2982
+
2983
+ bwidth = right - left
2984
+ bheight = bottom - top
2985
+
2986
+ newCentreX = left + bwidth / 2.0
2987
+ newCentreY = top + bheight / 2.0
2988
+
2989
+ for i in range(len(self._points)):
2990
+ self._points[i] = self._points[i][0] - newCentreX, self._points[i][1] - newCentreY
2991
+ self._xpos += newCentreX
2992
+ self._ypos += newCentreY
2993
+
2994
+ def HitTest(self, x, y):
2995
+ """Hit text
2996
+
2997
+ :param `x`: the x position
2998
+ :param `y`: the y position
2999
+
3000
+ """
3001
+ # Imagine four lines radiating from this point. If all of these lines
3002
+ # hit the polygon, we're inside it, otherwise we're not. Obviously
3003
+ # we'd need more radiating lines to be sure of correct results for
3004
+ # very strange (concave) shapes.
3005
+ endPointsX = [x, x + 1000, x, x - 1000]
3006
+ endPointsY = [y - 1000, y, y + 1000, y]
3007
+
3008
+ xpoints = []
3009
+ ypoints = []
3010
+
3011
+ for point in self._points:
3012
+ xpoints.append(point[0] + self._xpos)
3013
+ ypoints.append(point[1] + self._ypos)
3014
+
3015
+ # We assume it's inside the polygon UNLESS one or more
3016
+ # lines don't hit the outline.
3017
+ isContained = True
3018
+
3019
+ for i in range(4):
3020
+ if not PolylineHitTest(xpoints, ypoints, x, y, endPointsX[i], endPointsY[i]):
3021
+ isContained = False
3022
+
3023
+ if not isContained:
3024
+ return False
3025
+
3026
+ nearest_attachment = 0
3027
+
3028
+ # If a hit, check the attachment points within the object
3029
+ nearest = 999999
3030
+
3031
+ for i in range(self.GetNumberOfAttachments()):
3032
+ e = self.GetAttachmentPositionEdge(i)
3033
+ if e:
3034
+ xp, yp = e
3035
+ l = math.sqrt((xp - x) * (xp - x) + (yp - y) * (yp - y))
3036
+ if l < nearest:
3037
+ nearest = l
3038
+ nearest_attachment = i
3039
+
3040
+ return nearest_attachment, nearest
3041
+
3042
+ # Really need to be able to reset the shape! Otherwise, if the
3043
+ # points ever go to zero, we've lost it, and can't resize.
3044
+ def SetSize(self, new_width, new_height, recursive = True):
3045
+ """
3046
+ Set the size
3047
+
3048
+ :param `new_width`: the width
3049
+ :param `new_height`: the height
3050
+ :param `recursive`: not used
3051
+
3052
+ """
3053
+ self.SetAttachmentSize(new_width, new_height)
3054
+
3055
+ # Multiply all points by proportion of new size to old size
3056
+ x_proportion = abs(float(new_width) / self._originalWidth)
3057
+ y_proportion = abs(float(new_height) / self._originalHeight)
3058
+
3059
+ for i in range(max(len(self._points), len(self._originalPoints))):
3060
+ self._points[i] = wx.Point(*map(int, (self._originalPoints[i][0] * x_proportion, self._originalPoints[i][1] * y_proportion)))
3061
+
3062
+ self._boundWidth = abs(new_width)
3063
+ self._boundHeight = abs(new_height)
3064
+ self.SetDefaultRegionSize()
3065
+
3066
+ # Make the original points the same as the working points
3067
+ def UpdateOriginalPoints(self):
3068
+ """
3069
+ If we've changed the shape, must make the original points match the
3070
+ working points with this function.
3071
+
3072
+ """
3073
+ self._originalPoints = []
3074
+
3075
+ for point in self._points:
3076
+ original_point = wx.RealPoint(point[0], point[1])
3077
+ self._originalPoints.append(original_point)
3078
+
3079
+ self.CalculateBoundingBox()
3080
+ self._originalWidth = self._boundWidth
3081
+ self._originalHeight = self._boundHeight
3082
+
3083
+ def AddPolygonPoint(self, pos):
3084
+ """
3085
+ Add a control point after the given point.
3086
+
3087
+ :param `pos`: position of point
3088
+
3089
+ """
3090
+ try:
3091
+ firstPoint = self._points[pos]
3092
+ except ValueError:
3093
+ firstPoint = self._points[0]
3094
+
3095
+ try:
3096
+ secondPoint = self._points[pos + 1]
3097
+ except ValueError:
3098
+ secondPoint = self._points[0]
3099
+
3100
+ x = (secondPoint[0] - firstPoint[0]) / 2.0 + firstPoint[0]
3101
+ y = (secondPoint[1] - firstPoint[1]) / 2.0 + firstPoint[1]
3102
+ point = wx.RealPoint(x, y)
3103
+
3104
+ if pos >= len(self._points) - 1:
3105
+ self._points.append(point)
3106
+ else:
3107
+ self._points.insert(pos + 1, point)
3108
+
3109
+ self.UpdateOriginalPoints()
3110
+
3111
+ if self._selected:
3112
+ self.DeleteControlPoints()
3113
+ self.MakeControlPoints()
3114
+
3115
+ def DeletePolygonPoint(self, pos):
3116
+ """
3117
+
3118
+ Delete the given control point.
3119
+
3120
+ :param `pos`: position of point
3121
+
3122
+ """
3123
+ if pos < len(self._points):
3124
+ del self._points[pos]
3125
+ self.UpdateOriginalPoints()
3126
+ if self._selected:
3127
+ self.DeleteControlPoints()
3128
+ self.MakeControlPoints()
3129
+
3130
+ # Assume (x1, y1) is centre of box (most generally, line end at box)
3131
+ def GetPerimeterPoint(self, x1, y1, x2, y2):
3132
+ """
3133
+ Get the perimeter point.
3134
+
3135
+ :param `x1`: the x1 position
3136
+ :param `y1`: the y1 position
3137
+ :param `x2`: the x2 position
3138
+ :param `y2`: the y2 position
3139
+
3140
+ """
3141
+ # First check for situation where the line is vertical,
3142
+ # and we would want to connect to a point on that vertical --
3143
+ # oglFindEndForPolyline can't cope with this (the arrow
3144
+ # gets drawn to the wrong place).
3145
+ if self._attachmentMode == ATTACHMENT_MODE_NONE and x1 == x2:
3146
+ # Look for the point we'd be connecting to. This is
3147
+ # a heuristic...
3148
+ for point in self._points:
3149
+ if point[0] == 0:
3150
+ if y2 > y1 and point[1] > 0:
3151
+ return point[0] + self._xpos, point[1] + self._ypos
3152
+ elif y2 < y1 and point[1] < 0:
3153
+ return point[0] + self._xpos, point[1] + self._ypos
3154
+
3155
+ xpoints = []
3156
+ ypoints = []
3157
+ for point in self._points:
3158
+ xpoints.append(point[0] + self._xpos)
3159
+ ypoints.append(point[1] + self._ypos)
3160
+
3161
+ return FindEndForPolyline(xpoints, ypoints, x1, y1, x2, y2)
3162
+
3163
+ def OnDraw(self, dc):
3164
+ """The draw handler."""
3165
+ if self._shadowMode != SHADOW_NONE:
3166
+ if self._shadowBrush:
3167
+ dc.SetBrush(self._shadowBrush)
3168
+ dc.SetPen(TransparentPen)
3169
+
3170
+ dc.DrawPolygon(self._points, *map(int, (self._xpos + self._shadowOffsetX, self._ypos, self._shadowOffsetY)))
3171
+
3172
+ if self._pen:
3173
+ if self._pen.GetWidth() == 0:
3174
+ dc.SetPen(TransparentPen)
3175
+ else:
3176
+ dc.SetPen(self._pen)
3177
+ if self._brush:
3178
+ dc.SetBrush(self._brush)
3179
+ dc.DrawPolygon(self._points, *map(int, (self._xpos, self._ypos)))
3180
+
3181
+ def OnDrawOutline(self, dc, x, y, w, h):
3182
+ """The draw outline handler."""
3183
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
3184
+ # Multiply all points by proportion of new size to old size
3185
+ x_proportion = abs(float(w) / self._originalWidth)
3186
+ y_proportion = abs(float(h) / self._originalHeight)
3187
+
3188
+ intPoints = []
3189
+ for point in self._originalPoints:
3190
+ intPoints.append(wx.Point(*map(int, (x_proportion * point[0], y_proportion * point[1]))))
3191
+ dc.DrawPolygon(intPoints, *map(int, (x, y)))
3192
+
3193
+ # Make as many control points as there are vertices
3194
+ def MakeControlPoints(self):
3195
+ """Make control points."""
3196
+ for point in self._points:
3197
+ control = PolygonControlPoint(self._canvas, self, CONTROL_POINT_SIZE, point, point[0], point[1])
3198
+ self._canvas.AddShape(control)
3199
+ self._controlPoints.append(control)
3200
+
3201
+ def ResetControlPoints(self):
3202
+ """Reset control points."""
3203
+ for i in range(min(len(self._points), len(self._controlPoints))):
3204
+ point = self._points[i]
3205
+ self._controlPoints[i]._xoffset = point[0]
3206
+ self._controlPoints[i]._yoffset = point[1]
3207
+ self._controlPoints[i].polygonVertex = point
3208
+
3209
+ def GetNumberOfAttachments(self):
3210
+ """Get number of attachments."""
3211
+ maxN = max(len(self._points) - 1, 0)
3212
+ for point in self._attachmentPoints:
3213
+ if point._id > maxN:
3214
+ maxN = point._id
3215
+ return maxN + 1
3216
+
3217
+ def GetAttachmentPosition(self, attachment, nth = 0, no_arcs = 1, line = None):
3218
+ """
3219
+ Get attachment position.
3220
+
3221
+ :param `attachment`: the attachment ???
3222
+ :param `nth`: get nth attachment ???
3223
+ :param `no_arcs`: ???
3224
+ :param `line`: ???
3225
+
3226
+ """
3227
+ if self._attachmentMode == ATTACHMENT_MODE_EDGE and self._points and attachment < len(self._points):
3228
+ point = self._points[0]
3229
+ return point[0] + self._xpos, point[1] + self._ypos
3230
+ return Shape.GetAttachmentPosition(self, attachment, nth, no_arcs, line)
3231
+
3232
+ def AttachmentIsValid(self, attachment):
3233
+ """
3234
+ Is attachment valid?
3235
+
3236
+ :param `attachment`: ???
3237
+
3238
+ """
3239
+ if not self._points:
3240
+ return False
3241
+
3242
+ if attachment >= 0 and attachment < len(self._points):
3243
+ return True
3244
+
3245
+ for point in self._attachmentPoints:
3246
+ if point._id == attachment:
3247
+ return True
3248
+
3249
+ return False
3250
+
3251
+ def Rotate(self, x, y, theta):
3252
+ """
3253
+ Rotate about the given axis by the given amount in radians.
3254
+
3255
+ :param `x`: the x position
3256
+ :param `y`: the y position
3257
+ :param `theta`: the theta
3258
+
3259
+ """
3260
+
3261
+ actualTheta = theta - self._rotation
3262
+
3263
+ # Rotate attachment points
3264
+ sinTheta = math.sin(actualTheta)
3265
+ cosTheta = math.cos(actualTheta)
3266
+
3267
+ for point in self._attachmentPoints:
3268
+ x1 = point._x
3269
+ y1 = point._y
3270
+
3271
+ point._x = x1 * cosTheta - y1 * sinTheta + x * (1 - cosTheta) + y * sinTheta
3272
+ point._y = x1 * sinTheta + y1 * cosTheta + y * (1 - cosTheta) + x * sinTheta
3273
+
3274
+ for i in range(len(self._points)):
3275
+ x1, y1 = self._points[i]
3276
+
3277
+ self._points[i] = x1 * cosTheta - y1 * sinTheta + x * (1 - cosTheta) + y * sinTheta, x1 * sinTheta + y1 * cosTheta + y * (1 - cosTheta) + x * sinTheta
3278
+
3279
+ for i in range(len(self._originalPoints)):
3280
+ x1, y1 = self._originalPoints[i]
3281
+
3282
+ self._originalPoints[i] = x1 * cosTheta - y1 * sinTheta + x * (1 - cosTheta) + y * sinTheta, x1 * sinTheta + y1 * cosTheta + y * (1 - cosTheta) + x * sinTheta
3283
+
3284
+ # Added by Pierre Hjälm. If we don't do this the outline will be
3285
+ # the wrong size. Hopefully it won't have any ill effects.
3286
+ self.UpdateOriginalPoints()
3287
+
3288
+ self._rotation = theta
3289
+
3290
+ self.CalculatePolygonCentre()
3291
+ self.CalculateBoundingBox()
3292
+ self.ResetControlPoints()
3293
+
3294
+ # Control points ('handles') redirect control to the actual shape, to
3295
+ # make it easier to override sizing behaviour.
3296
+ def OnSizingDragLeft(self, pt, draw, x, y, keys = 0, attachment = 0):
3297
+ """The sizing drag left handler."""
3298
+ dc = wx.MemoryDC()
3299
+ dc.SelectObject(self.GetCanvas().GetBuffer())
3300
+ self.GetCanvas().PrepareDC(dc)
3301
+ dc.SetLogicalFunction(OGLRBLF)
3302
+
3303
+ dottedPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)
3304
+ dc.SetPen(dottedPen)
3305
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
3306
+
3307
+ # Code for CTRL-drag in C++ version commented out
3308
+
3309
+ pt.CalculateNewSize(x, y)
3310
+
3311
+ self.GetEventHandler().OnDrawOutline(dc, self.GetX(), self.GetY(), pt.GetNewSize()[0], pt.GetNewSize()[1])
3312
+
3313
+ def OnSizingBeginDragLeft(self, pt, x, y, keys = 0, attachment = 0):
3314
+ """The sizing begin drag left handler."""
3315
+ dc = wx.MemoryDC()
3316
+ dc.SelectObject(self.GetCanvas().GetBuffer())
3317
+ self.GetCanvas().PrepareDC(dc)
3318
+ dc.SetLogicalFunction(OGLRBLF)
3319
+
3320
+ self.Erase(dc)
3321
+
3322
+ bound_x, bound_y = self.GetBoundingBoxMin()
3323
+
3324
+ dist = math.sqrt((x - self.GetX()) * (x - self.GetX()) + (y - self.GetY()) * (y - self.GetY()))
3325
+
3326
+ pt._originalDistance = dist
3327
+ pt._originalSize[0] = bound_x
3328
+ pt._originalSize[1] = bound_y
3329
+
3330
+ if pt._originalDistance == 0:
3331
+ pt._originalDistance = 0.0001
3332
+
3333
+ dottedPen = wx.Pen(wx.BLACK, 1, wx.PENSTYLE_DOT)
3334
+ dc.SetPen(dottedPen)
3335
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
3336
+
3337
+ # Code for CTRL-drag in C++ version commented out
3338
+
3339
+ pt.CalculateNewSize(x, y)
3340
+
3341
+ self.GetEventHandler().OnDrawOutline(dc, self.GetX(), self.GetY(), pt.GetNewSize()[0], pt.GetNewSize()[1])
3342
+
3343
+ self._canvas.CaptureMouse()
3344
+
3345
+ def OnSizingEndDragLeft(self, pt, x, y, keys = 0, attachment = 0):
3346
+ """The sizing end drag left handler."""
3347
+ dc = wx.MemoryDC()
3348
+ dc.SelectObject(self.GetCanvas().GetBuffer())
3349
+ self.GetCanvas().PrepareDC(dc)
3350
+
3351
+ if self._canvas.HasCapture():
3352
+ self._canvas.ReleaseMouse()
3353
+ dc.SetLogicalFunction(wx.COPY)
3354
+
3355
+ # If we're changing shape, must reset the original points
3356
+ if keys & KEY_CTRL:
3357
+ self.CalculateBoundingBox()
3358
+ self.CalculatePolygonCentre()
3359
+ else:
3360
+ self.SetSize(pt.GetNewSize()[0], pt.GetNewSize()[1])
3361
+
3362
+ self.Recompute()
3363
+ self.ResetControlPoints()
3364
+ self.Move(dc, self.GetX(), self.GetY())
3365
+ if not self._canvas.GetQuickEditMode():
3366
+ self._canvas.Redraw(dc)
3367
+
3368
+
3369
+ class EllipseShape(Shape):
3370
+ """
3371
+ The :class:`EllipseShape` class behaves similarly to the
3372
+ :class`RectangleShape` but is elliptical.
3373
+
3374
+ """
3375
+ def __init__(self, w, h):
3376
+ """
3377
+ Default class constructor
3378
+
3379
+ :param `w`: the width
3380
+ :param `h`: the height
3381
+
3382
+ """
3383
+ Shape.__init__(self)
3384
+ self._width = w
3385
+ self._height = h
3386
+ self.SetDefaultRegionSize()
3387
+
3388
+ def GetBoundingBoxMin(self):
3389
+ """Get the minimum bounding box."""
3390
+ return self._width, self._height
3391
+
3392
+ def GetPerimeterPoint(self, x1, y1, x2, y2):
3393
+ """
3394
+ Get the perimeter point.
3395
+
3396
+ :param `x1`: the x1 position
3397
+ :param `y1`: the y1 position
3398
+ :param `x2`: the x2 position
3399
+ :param `y2`: the y2 position
3400
+
3401
+ """
3402
+ bound_x, bound_y = self.GetBoundingBoxMax()
3403
+
3404
+ return DrawArcToEllipse(self._xpos, self._ypos, bound_x, bound_y, x2, y2, x1, y1)
3405
+
3406
+ def GetWidth(self):
3407
+ """Get the width."""
3408
+ return self._width
3409
+
3410
+ def GetHeight(self):
3411
+ """Get the height."""
3412
+ return self._height
3413
+
3414
+ def SetWidth(self, w):
3415
+ """
3416
+ Set the width.
3417
+
3418
+ :param `w`: the width
3419
+
3420
+ """
3421
+ self._width = w
3422
+
3423
+ def SetHeight(self, h):
3424
+ """
3425
+ Set the height.
3426
+
3427
+ :param `h`: the height
3428
+
3429
+ """
3430
+ self._height = h
3431
+
3432
+ def OnDraw(self, dc):
3433
+ """The draw handler."""
3434
+ if self._shadowMode != SHADOW_NONE:
3435
+ if self._shadowBrush:
3436
+ dc.SetBrush(self._shadowBrush)
3437
+ dc.SetPen(TransparentPen)
3438
+ dc.DrawEllipse(*map(int, (self._xpos - self.GetWidth() / 2.0 + self._shadowOffsetX,
3439
+ self._ypos - self.GetHeight() / 2.0 + self._shadowOffsetY,
3440
+ self.GetWidth(), self.GetHeight())))
3441
+
3442
+ if self._pen:
3443
+ if self._pen.GetWidth() == 0:
3444
+ dc.SetPen(TransparentPen)
3445
+ else:
3446
+ dc.SetPen(self._pen)
3447
+ if self._brush:
3448
+ dc.SetBrush(self._brush)
3449
+ dc.DrawEllipse(*map(int, (self._xpos - self.GetWidth() / 2.0, self._ypos - self.GetHeight() / 2.0, self.GetWidth(), self.GetHeight())))
3450
+
3451
+ def SetSize(self, x, y, recursive = True):
3452
+ """
3453
+ Set the size.
3454
+
3455
+ :param `x`: the width
3456
+ :param `y`: the height
3457
+ :recursive: not used
3458
+
3459
+ """
3460
+ self.SetAttachmentSize(x, y)
3461
+ self._width = x
3462
+ self._height = y
3463
+ self.SetDefaultRegionSize()
3464
+
3465
+ def GetNumberOfAttachments(self):
3466
+ """Get number of attachments."""
3467
+ return Shape.GetNumberOfAttachments(self)
3468
+
3469
+ # There are 4 attachment points on an ellipse - 0 = top, 1 = right,
3470
+ # 2 = bottom, 3 = left.
3471
+ def GetAttachmentPosition(self, attachment, nth = 0, no_arcs = 1, line = None):
3472
+ """
3473
+ Get attachment position.
3474
+
3475
+ :param `attachment`: the attachment ???
3476
+ :param `nth`: get nth attachment ???
3477
+ :param `no_arcs`: ???
3478
+ :param `line`: ???
3479
+
3480
+ """
3481
+ if self._attachmentMode == ATTACHMENT_MODE_BRANCHING:
3482
+ return Shape.GetAttachmentPosition(self, attachment, nth, no_arcs, line)
3483
+
3484
+ if self._attachmentMode != ATTACHMENT_MODE_NONE:
3485
+ top = self._ypos + self._height / 2.0
3486
+ bottom = self._ypos - self._height / 2.0
3487
+ left = self._xpos - self._width / 2.0
3488
+ right = self._xpos + self._width / 2.0
3489
+
3490
+ physicalAttachment = self.LogicalToPhysicalAttachment(attachment)
3491
+
3492
+ if physicalAttachment == 0:
3493
+ if self._spaceAttachments:
3494
+ x = left + (nth + 1) * self._width / (no_arcs + 1.0)
3495
+ else:
3496
+ x = self._xpos
3497
+ y = top
3498
+ # We now have the point on the bounding box: but get the point
3499
+ # on the ellipse by imagining a vertical line from
3500
+ # (x, self._ypos - self._height - 500) to (x, self._ypos) intersecting
3501
+ # the ellipse.
3502
+
3503
+ return DrawArcToEllipse(self._xpos, self._ypos, self._width, self._height, x, self._ypos - self._height - 500, x, self._ypos)
3504
+ elif physicalAttachment == 1:
3505
+ x = right
3506
+ if self._spaceAttachments:
3507
+ y = bottom + (nth + 1) * self._height / (no_arcs + 1.0)
3508
+ else:
3509
+ y = self._ypos
3510
+ return DrawArcToEllipse(self._xpos, self._ypos, self._width, self._height, self._xpos + self._width + 500, y, self._xpos, y)
3511
+ elif physicalAttachment == 2:
3512
+ if self._spaceAttachments:
3513
+ x = left + (nth + 1) * self._width / (no_arcs + 1.0)
3514
+ else:
3515
+ x = self._xpos
3516
+ y = bottom
3517
+ return DrawArcToEllipse(self._xpos, self._ypos, self._width, self._height, x, self._ypos + self._height + 500, x, self._ypos)
3518
+ elif physicalAttachment == 3:
3519
+ x = left
3520
+ if self._spaceAttachments:
3521
+ y = bottom + (nth + 1) * self._height / (no_arcs + 1.0)
3522
+ else:
3523
+ y = self._ypos
3524
+ return DrawArcToEllipse(self._xpos, self._ypos, self._width, self._height, self._xpos - self._width - 500, y, self._xpos, y)
3525
+ else:
3526
+ return Shape.GetAttachmentPosition(self, attachment, x, y, nth, no_arcs, line)
3527
+ else:
3528
+ return self._xpos, self._ypos
3529
+
3530
+
3531
+ class CircleShape(EllipseShape):
3532
+ """
3533
+ The :class:`CircleShape` class is an :class:`EllipseShape` whose width
3534
+ and height are the same.
3535
+ """
3536
+ def __init__(self, diameter):
3537
+ """
3538
+ Default class constructor
3539
+
3540
+ :param `diameter`: the diameter
3541
+
3542
+ """
3543
+ EllipseShape.__init__(self, diameter, diameter)
3544
+ self.SetMaintainAspectRatio(True)
3545
+
3546
+ def GetPerimeterPoint(self, x1, y1, x2, y2):
3547
+ """
3548
+ Get the perimeter point.
3549
+
3550
+ :param `x1`: ???
3551
+ :param `y1`: ???
3552
+ :param `x2`: ???
3553
+ :param `y2`: ???
3554
+ :returns: ???
3555
+
3556
+ """
3557
+ return FindEndForCircle(self._width / 2.0, self._xpos, self._ypos, x2, y2)
3558
+
3559
+
3560
+ class TextShape(RectangleShape):
3561
+ """
3562
+ The :class:`TextShape` class like :class:`wx.RectangleShape` but only the
3563
+ text is displayed.
3564
+ """
3565
+ def __init__(self, width, height):
3566
+ """
3567
+ Default class constructor
3568
+
3569
+ :param `width`: the width
3570
+ :param `height`: the height
3571
+
3572
+ """
3573
+ RectangleShape.__init__(self, width, height)
3574
+
3575
+ def OnDraw(self, dc):
3576
+ """not implemented???"""
3577
+ pass
3578
+
3579
+
3580
+ class ShapeRegion(object):
3581
+ """The :class:`ShapeRegion` class."""
3582
+ def __init__(self, region = None):
3583
+ """
3584
+ Default class constructor
3585
+
3586
+ :param `region`: a parent region or None???
3587
+
3588
+ """
3589
+ if region:
3590
+ self._regionText = region._regionText
3591
+ self._regionName = region._regionName
3592
+ self._textColour = region._textColour
3593
+
3594
+ self._font = region._font
3595
+ self._minHeight = region._minHeight
3596
+ self._minWidth = region._minWidth
3597
+ self._width = region._width
3598
+ self._height = region._height
3599
+ self._x = region._x
3600
+ self._y = region._y
3601
+
3602
+ self._regionProportionX = region._regionProportionX
3603
+ self._regionProportionY = region._regionProportionY
3604
+ self._formatMode = region._formatMode
3605
+ self._actualColourObject = region._actualColourObject
3606
+ self._actualPenObject = None
3607
+ self._penStyle = region._penStyle
3608
+ self._penColour = region._penColour
3609
+
3610
+ self.ClearText()
3611
+ for line in region._formattedText:
3612
+ new_line = ShapeTextLine(line.GetX(), line.GetY(), line.GetText())
3613
+ self._formattedText.append(new_line)
3614
+ else:
3615
+ self._regionText = ""
3616
+ self._font = NormalFont
3617
+ self._minHeight = 5.0
3618
+ self._minWidth = 5.0
3619
+ self._width = 0.0
3620
+ self._height = 0.0
3621
+ self._x = 0.0
3622
+ self._y = 0.0
3623
+
3624
+ self._regionProportionX = -1.0
3625
+ self._regionProportionY = -1.0
3626
+ self._formatMode = FORMAT_CENTRE_HORIZ | FORMAT_CENTRE_VERT
3627
+ self._regionName = ""
3628
+ self._textColour = "BLACK"
3629
+ self._penColour = "BLACK"
3630
+ self._penStyle = wx.PENSTYLE_SOLID
3631
+ self._actualColourObject = wx.TheColourDatabase.Find("BLACK")
3632
+ self._actualPenObject = None
3633
+
3634
+ self._formattedText = []
3635
+
3636
+ def ClearText(self):
3637
+ """Clear the text."""
3638
+ self._formattedText = []
3639
+
3640
+ def SetFont(self, f):
3641
+ """
3642
+ Set the font.
3643
+
3644
+ :param `f`: an instance of :class:`wx.Font`
3645
+ """
3646
+ self._font = f
3647
+
3648
+ def SetMinSize(self, w, h):
3649
+ """
3650
+ Set the minumum size.
3651
+
3652
+ :param `w`: the minimum width
3653
+ :Param `h`: the minimum height
3654
+
3655
+ """
3656
+ self._minWidth = w
3657
+ self._minHeight = h
3658
+
3659
+ def SetSize(self, w, h):
3660
+ """
3661
+ Set the size.
3662
+
3663
+ :param `w`: the width
3664
+ :Param `h`: the jeight
3665
+
3666
+ """
3667
+ self._width = w
3668
+ self._height = h
3669
+
3670
+ def SetPosition(self, xp, yp):
3671
+ """
3672
+ Set the position.
3673
+
3674
+ :param `xp`: the x position
3675
+ :Param `yp`: the y position
3676
+
3677
+ """
3678
+ self._x = xp
3679
+ self._y = yp
3680
+
3681
+ def SetProportions(self, xp, yp):
3682
+ """
3683
+ Set the proportions.
3684
+
3685
+ :param `xp`: the x region proportion
3686
+ :Param `yp`: the y region proportion
3687
+
3688
+ """
3689
+ self._regionProportionX = xp
3690
+ self._regionProportionY = yp
3691
+
3692
+ def SetFormatMode(self, mode):
3693
+ """
3694
+ Set the format mode of the region.
3695
+
3696
+ :param `mode`: can be a bit list of the following
3697
+
3698
+ ============================== ==============================
3699
+ Format mode Description
3700
+ ============================== ==============================
3701
+ `FORMAT_NONE` No formatting
3702
+ `FORMAT_CENTRE_HORIZ` Horizontal centring
3703
+ `FORMAT_CENTRE_VERT` Vertical centring
3704
+ ============================== ==============================
3705
+
3706
+ """
3707
+ self._formatMode = mode
3708
+
3709
+ def SetColour(self, col):
3710
+ """
3711
+ Set the colour.
3712
+
3713
+ :param str `col`: a valid colour name,
3714
+ see :class:`wx.ColourDatabase`
3715
+
3716
+ """
3717
+ self._textColour = col
3718
+ self._actualColourObject = col
3719
+
3720
+ def GetActualColourObject(self):
3721
+ """Get the actual colour object from the :class:`wx.ColourDatabase`."""
3722
+ self._actualColourObject = wx.TheColourDatabase.Find(self.GetColour())
3723
+ return self._actualColourObject
3724
+
3725
+ def SetPenColour(self, col):
3726
+ """
3727
+ Set the pen colour.
3728
+
3729
+ :param str `col`: a valid colour name,
3730
+ see :class:`wx.ColourDatabase`
3731
+
3732
+ """
3733
+ self._penColour = col
3734
+ self._actualPenObject = None
3735
+
3736
+ def GetActualPen(self):
3737
+ """
3738
+ Get actual pen.
3739
+
3740
+ :note: Returns NULL if the pen is invisible
3741
+ (different to pen being transparent; indicates that
3742
+ region boundary should not be drawn.)
3743
+
3744
+ """
3745
+ if self._actualPenObject:
3746
+ return self._actualPenObject
3747
+
3748
+ if not self._penColour:
3749
+ return None
3750
+ if self._penColour=="Invisible":
3751
+ return None
3752
+ self._actualPenObject = wx.Pen(self._penColour, 1, self._penStyle)
3753
+ return self._actualPenObject
3754
+
3755
+ def SetText(self, s):
3756
+ """
3757
+ Set the text.
3758
+
3759
+ :param str `s`: the text
3760
+
3761
+ """
3762
+ self._regionText = s
3763
+
3764
+ def SetName(self, s):
3765
+ """
3766
+ Set the name.
3767
+
3768
+ :param str `s`: the name
3769
+
3770
+ """
3771
+ self._regionName = s
3772
+
3773
+ def GetText(self):
3774
+ """Get the text."""
3775
+ return self._regionText
3776
+
3777
+ def GetFont(self):
3778
+ """Get the font."""
3779
+ return self._font
3780
+
3781
+ def GetMinSize(self):
3782
+ """Get the minimum size."""
3783
+ return self._minWidth, self._minHeight
3784
+
3785
+ def GetProportion(self):
3786
+ """Get the proportion."""
3787
+ return self._regionProportionX, self._regionProportionY
3788
+
3789
+ def GetSize(self):
3790
+ """Get the size."""
3791
+ return self._width, self._height
3792
+
3793
+ def GetPosition(self):
3794
+ """Get the position."""
3795
+ return self._x, self._y
3796
+
3797
+ def GetFormatMode(self):
3798
+ """Get the format mode."""
3799
+ return self._formatMode
3800
+
3801
+ def GetName(self):
3802
+ """Get the name."""
3803
+ return self._regionName
3804
+
3805
+ def GetColour(self):
3806
+ """Get the colour."""
3807
+ return self._textColour
3808
+
3809
+ def GetFormattedText(self):
3810
+ """Get the formatted text."""
3811
+ return self._formattedText
3812
+
3813
+ def GetPenColour(self):
3814
+ """Get the pen colour"""
3815
+ return self._penColour
3816
+
3817
+ def GetPenStyle(self):
3818
+ """Get the pen style."""
3819
+ return self._penStyle
3820
+
3821
+ def SetPenStyle(self, style):
3822
+ """
3823
+ Set the pen style.
3824
+
3825
+ :param `style`: the style, see :class:`wx.Pen`
3826
+
3827
+ """
3828
+ self._penStyle = style
3829
+ self._actualPenObject = None
3830
+
3831
+ def GetWidth(self):
3832
+ """Get the width."""
3833
+ return self._width
3834
+
3835
+ def GetHeight(self):
3836
+ """Get the height."""
3837
+ return self._height
3838
+
3839
+
3840
+ class ControlPoint(RectangleShape):
3841
+ """The :class:`wx.ControlPoint` class."""
3842
+ def __init__(self, theCanvas, object, size, the_xoffset, the_yoffset, the_type):
3843
+ """
3844
+ Default class constructor
3845
+
3846
+ :param `theCanvas`: a :class:`~lib.ogl.Canvas`
3847
+ :param `object`: the shape, instance of :class:`~lib.ogl.Shape`
3848
+ :param float `size`: the size
3849
+ :param float `the_xoffset`: the x position
3850
+ :param float `the_yoffset`: the y position
3851
+ :param int `the_type`: one of the following types ???
3852
+
3853
+ ======================================== ==================================
3854
+ Control point type Description
3855
+ ======================================== ==================================
3856
+ `CONTROL_POINT_VERTICAL` Vertical
3857
+ `CONTROL_POINT_HORIZONTAL` Horizontal
3858
+ `CONTROL_POINT_DIAGONAL` Diagonal
3859
+ ======================================== ==================================
3860
+
3861
+ """
3862
+ RectangleShape.__init__(self, size, size)
3863
+
3864
+ self._canvas = theCanvas
3865
+ self._shape = object
3866
+ self._xoffset = the_xoffset
3867
+ self._yoffset = the_yoffset
3868
+ self._type = the_type
3869
+ self.SetPen(BlackForegroundPen)
3870
+ self.SetBrush(wx.BLACK_BRUSH)
3871
+ self._oldCursor = None
3872
+ self._visible = True
3873
+ self._eraseObject = True
3874
+
3875
+ # Don't even attempt to draw any text - waste of time
3876
+ def OnDrawContents(self, dc):
3877
+ """not implemented???"""
3878
+ pass
3879
+
3880
+ def OnDraw(self, dc):
3881
+ """The draw handler."""
3882
+ self._xpos = self._shape.GetX() + self._xoffset
3883
+ self._ypos = self._shape.GetY() + self._yoffset
3884
+ RectangleShape.OnDraw(self, dc)
3885
+
3886
+ def OnErase(self, dc):
3887
+ """The erase handler."""
3888
+ RectangleShape.OnErase(self, dc)
3889
+
3890
+ # Implement resizing of canvas object
3891
+ def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
3892
+ """The drag left handler."""
3893
+ self._shape.GetEventHandler().OnSizingDragLeft(self, draw, x, y, keys, attachment)
3894
+
3895
+ def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
3896
+ """The begin drag left handler."""
3897
+ self._shape.GetEventHandler().OnSizingBeginDragLeft(self, x, y, keys, attachment)
3898
+
3899
+ def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
3900
+ """The end drag left handler."""
3901
+ self._shape.GetEventHandler().OnSizingEndDragLeft(self, x, y, keys, attachment)
3902
+
3903
+ def GetNumberOfAttachments(self):
3904
+ """Get the number of attachments."""
3905
+ return 1
3906
+
3907
+ def GetAttachmentPosition(self, attachment, nth = 0, no_arcs = 1, line = None):
3908
+ """
3909
+ Get the attachment position.
3910
+
3911
+ :param `attachment`: the attachment ???
3912
+ :param `nth`: get nth attachment ???
3913
+ :param `no_arcs`: ???
3914
+ :param `line`: ???
3915
+
3916
+ """
3917
+ return self._xpos, self._ypos
3918
+
3919
+ def SetEraseObject(self, er):
3920
+ """
3921
+ Set the erase object ???
3922
+
3923
+ :param `er`: the object
3924
+
3925
+ """
3926
+ self._eraseObject = er
3927
+
3928
+
3929
+ class PolygonControlPoint(ControlPoint):
3930
+ """The :class:`PolygonControlPoint` class."""
3931
+ def __init__(self, theCanvas, object, size, vertex, the_xoffset, the_yoffset):
3932
+ """
3933
+ Default class constructor
3934
+
3935
+ :param `theCanvas`: a :class:`~lib.ogl.Canvas`
3936
+ :param `object`: the shape, instance of :class:`~lib.ogl.Shape`
3937
+ :param float `size`: the size
3938
+ :param `vertext`: the vertex
3939
+ :param float `the_xoffset`: the x position
3940
+ :param float `the_yoffset`: the y position
3941
+ :param int `the_type`: one of the following types ???
3942
+
3943
+ ======================================== ==================================
3944
+ Control point type Description
3945
+ ======================================== ==================================
3946
+ `CONTROL_POINT_VERTICAL` Vertical
3947
+ `CONTROL_POINT_HORIZONTAL` Horizontal
3948
+ `CONTROL_POINT_DIAGONAL` Diagonal
3949
+ ======================================== ==================================
3950
+
3951
+ """
3952
+ ControlPoint.__init__(self, theCanvas, object, size, the_xoffset, the_yoffset, 0)
3953
+ self._polygonVertex = vertex
3954
+ self._originalDistance = 0.0
3955
+ self._newSize = wx.RealPoint()
3956
+ self._originalSize = wx.RealPoint()
3957
+
3958
+ def GetNewSize(self):
3959
+ """Get the new size."""
3960
+ return self._newSize
3961
+
3962
+ def CalculateNewSize(self, x, y):
3963
+ """
3964
+ Calculate what new size would be, at end of resize.
3965
+
3966
+ :param `x`: x ???
3967
+ :param `y`: y ???
3968
+
3969
+ """
3970
+ bound_x, bound_y = self.GetShape().GetBoundingBoxMax()
3971
+ dist = math.sqrt((x - self._shape.GetX()) * (x - self._shape.GetX()) + (y - self._shape.GetY()) * (y - self._shape.GetY()))
3972
+
3973
+ self._newSize[0] = dist / self._originalDistance * self._originalSize[0]
3974
+ self._newSize[1] = dist / self._originalDistance * self._originalSize[1]
3975
+
3976
+ # Implement resizing polygon or moving the vertex
3977
+ def OnDragLeft(self, draw, x, y, keys = 0, attachment = 0):
3978
+ """The drag left handler."""
3979
+ self._shape.GetEventHandler().OnSizingDragLeft(self, draw, x, y, keys, attachment)
3980
+
3981
+ def OnBeginDragLeft(self, x, y, keys = 0, attachment = 0):
3982
+ """The begin drag left handler."""
3983
+ self._shape.GetEventHandler().OnSizingBeginDragLeft(self, x, y, keys, attachment)
3984
+
3985
+ def OnEndDragLeft(self, x, y, keys = 0, attachment = 0):
3986
+ """The end drag left handler."""
3987
+ self._shape.GetEventHandler().OnSizingEndDragLeft(self, x, y, keys, attachment)
3988
+
3989
+ from .canvas import *
3990
+ from .lines import *
3991
+ from .composit import *