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
@@ -0,0 +1,2923 @@
1
+ #----------------------------------------------------------------------------
2
+ # Name: FCObjects.py
3
+ # Purpose: Contains all the drawing objects FloatCanvas supports
4
+ #
5
+ # Author:
6
+ #
7
+ # Created:
8
+ # Version:
9
+ # Date:
10
+ # Licence:
11
+ # Tags: phoenix-port, unittest, documented, py3-port
12
+ # (c) 2021 - 2024 Zombie
13
+ #----------------------------------------------------------------------------
14
+ """
15
+ This is where FloatCanvas defines its drawings objects.
16
+ """
17
+
18
+ import sys
19
+
20
+ import wx
21
+ import six
22
+
23
+ import numpy as N
24
+
25
+ from .Utilities import BBox
26
+ from wx.lib.floatcanvas.Utilities import Colors
27
+
28
+ mac = sys.platform.startswith("darwin")
29
+
30
+ ## A global variable to hold the Pixels per inch that wxWindows thinks is in use
31
+ ## This is used for scaling fonts.
32
+ ## This can't be computed on module __init__, because a wx.App might not have initialized yet.
33
+ global FontScale
34
+
35
+
36
+ def ComputeFontScale():
37
+ """
38
+ Compute the font scale.
39
+
40
+ A global variable to hold the scaling from pixel size to point size.
41
+ """
42
+ global FontScale
43
+ dc = wx.ScreenDC()
44
+ dc.SetFont(wx.Font(16, wx.FONTFAMILY_ROMAN, wx.FONTSTYLE_NORMAL, wx.FONTWEIGHT_NORMAL))
45
+ E = dc.GetTextExtent("X")
46
+ FontScale = 16/E[1]
47
+ del dc
48
+
49
+ # why do we do this here, causes a Sphinx build crash
50
+ #ComputeFontScale()
51
+
52
+ ## fixme: This should probably be re-factored into a class
53
+ _testBitmap = None
54
+
55
+ def _cycleidxs(indexcount, maxvalue, step):
56
+
57
+ """
58
+ Utility function used by _colorGenerator
59
+ """
60
+ def colormatch(color):
61
+ """Return True if the color comes back from the bitmap identically."""
62
+ if len(color) < 3:
63
+ return True
64
+ global _testBitmap
65
+ dc = wx.MemoryDC()
66
+ if not _testBitmap:
67
+ _testBitmap = wx.Bitmap(1, 1)
68
+ dc.SelectObject(_testBitmap)
69
+ dc.SetBackground(wx.BLACK_BRUSH)
70
+ dc.Clear()
71
+ dc.SetPen(wx.Pen(wx.Colour(*color), 4))
72
+ dc.DrawPoint(0,0)
73
+ if mac: # NOTE: can the Mac not just use the DC?
74
+ del dc # Mac can't work with bitmap when selected into a DC.
75
+ pdata = wx.AlphaPixelData(_testBitmap)
76
+ pacc = pdata.GetPixels()
77
+ pacc.MoveTo(pdata, 0, 0)
78
+ outcolor = pacc.Get()[:3]
79
+ else:
80
+ outcolor = dc.GetPixel(0,0)
81
+ return outcolor == color
82
+
83
+ if indexcount == 0:
84
+ yield ()
85
+ else:
86
+ for idx in range(0, maxvalue, step):
87
+ for tail in _cycleidxs(indexcount - 1, maxvalue, step):
88
+ color = (idx, ) + tail
89
+ if not colormatch(color):
90
+ continue
91
+ yield color
92
+
93
+
94
+ def _colorGenerator():
95
+
96
+ """
97
+ Generates a series of unique colors used to do hit-tests with the Hit
98
+ Test bitmap
99
+ """
100
+ return _cycleidxs(indexcount=3, maxvalue=256, step=1)
101
+
102
+
103
+ class DrawObject:
104
+ """
105
+ This is the base class for all the objects that can be drawn.
106
+
107
+ One must subclass from this (and an assortment of Mixins) to create
108
+ a new DrawObject, see for example :class:`~lib.floatcanvas.FloatCanvas.Circle`.
109
+
110
+ """
111
+ #This class contains a series of static dictionaries:
112
+
113
+ #* BrushList
114
+ #* PenList
115
+ #* FillStyleList
116
+ #* LineStyleList
117
+
118
+
119
+ def __init__(self, InForeground = False, IsVisible = True):
120
+ """
121
+ Default class constructor.
122
+
123
+ :param boolean `InForeground`: Define if object should be in foreground
124
+ or not
125
+ :param boolean `IsVisible`: Define if object should be visible
126
+
127
+ """
128
+ self.InForeground = InForeground
129
+
130
+ self._Canvas = None
131
+
132
+ self.HitColor = None
133
+ self.CallBackFuncs = {}
134
+
135
+ ## these are the defaults
136
+ self.HitAble = False
137
+ self.HitLine = True
138
+ self.HitFill = True
139
+ self.MinHitLineWidth = 3
140
+ self.HitLineWidth = 3 ## this gets re-set by the subclasses if necessary
141
+
142
+ self.Brush = None
143
+ self.Pen = None
144
+
145
+ self.FillStyle = "Solid"
146
+
147
+ self.Visible = IsVisible
148
+
149
+ # I pre-define all these as class variables to provide an easier
150
+ # interface, and perhaps speed things up by caching all the Pens
151
+ # and Brushes, although that may not help, as I think wx now
152
+ # does that on it's own. Send me a note if you know!
153
+
154
+ BrushList = {
155
+ ( None, "Transparent") : wx.TRANSPARENT_BRUSH,
156
+ ("Blue", "Solid") : wx.BLUE_BRUSH,
157
+ ("Green", "Solid") : wx.GREEN_BRUSH,
158
+ ("White", "Solid") : wx.WHITE_BRUSH,
159
+ ("Black", "Solid") : wx.BLACK_BRUSH,
160
+ ("Grey", "Solid") : wx.GREY_BRUSH,
161
+ ("MediumGrey", "Solid") : wx.MEDIUM_GREY_BRUSH,
162
+ ("LightGrey", "Solid") : wx.LIGHT_GREY_BRUSH,
163
+ ("Cyan", "Solid") : wx.CYAN_BRUSH,
164
+ ("Red", "Solid") : wx.RED_BRUSH
165
+ }
166
+ PenList = {
167
+ (None, "Transparent", 1) : wx.TRANSPARENT_PEN,
168
+ ("Green", "Solid", 1) : wx.GREEN_PEN,
169
+ ("White", "Solid", 1) : wx.WHITE_PEN,
170
+ ("Black", "Solid", 1) : wx.BLACK_PEN,
171
+ ("Grey", "Solid", 1) : wx.GREY_PEN,
172
+ ("MediumGrey", "Solid", 1) : wx.MEDIUM_GREY_PEN,
173
+ ("LightGrey", "Solid", 1) : wx.LIGHT_GREY_PEN,
174
+ ("Cyan", "Solid", 1) : wx.CYAN_PEN,
175
+ ("Red", "Solid", 1) : wx.RED_PEN
176
+ }
177
+
178
+ FillStyleList = {
179
+ "Transparent" : wx.BRUSHSTYLE_TRANSPARENT,
180
+ "Solid" : wx.BRUSHSTYLE_SOLID,
181
+ "BiDiagonalHatch": wx.BRUSHSTYLE_BDIAGONAL_HATCH,
182
+ "CrossDiagHatch" : wx.BRUSHSTYLE_CROSSDIAG_HATCH,
183
+ "FDiagonal_Hatch": wx.BRUSHSTYLE_FDIAGONAL_HATCH,
184
+ "CrossHatch" : wx.BRUSHSTYLE_CROSS_HATCH,
185
+ "HorizontalHatch": wx.BRUSHSTYLE_HORIZONTAL_HATCH,
186
+ "VerticalHatch" : wx.BRUSHSTYLE_VERTICAL_HATCH
187
+ }
188
+
189
+ LineStyleList = {
190
+ "Solid" : wx.PENSTYLE_SOLID,
191
+ "Transparent": wx.PENSTYLE_TRANSPARENT,
192
+ "Dot" : wx.PENSTYLE_DOT,
193
+ "LongDash" : wx.PENSTYLE_LONG_DASH,
194
+ "ShortDash" : wx.PENSTYLE_SHORT_DASH,
195
+ "DotDash" : wx.PENSTYLE_DOT_DASH,
196
+ }
197
+
198
+ def Bind(self, Event, CallBackFun):
199
+ """
200
+ Bind an event to the DrawObject
201
+
202
+ :param `Event`: see below for supported event types
203
+
204
+ - EVT_FC_LEFT_DOWN
205
+ - EVT_FC_LEFT_UP
206
+ - EVT_FC_LEFT_DCLICK
207
+ - EVT_FC_MIDDLE_DOWN
208
+ - EVT_FC_MIDDLE_UP
209
+ - EVT_FC_MIDDLE_DCLICK
210
+ - EVT_FC_RIGHT_DOWN
211
+ - EVT_FC_RIGHT_UP
212
+ - EVT_FC_RIGHT_DCLICK
213
+ - EVT_FC_ENTER_OBJECT
214
+ - EVT_FC_LEAVE_OBJECT
215
+
216
+ :param `CallBackFun`: the call back function for the event
217
+
218
+
219
+ """
220
+ ##fixme: Way too much Canvas Manipulation here!
221
+ self.CallBackFuncs[Event] = CallBackFun
222
+ self.HitAble = True
223
+ self._Canvas.UseHitTest = True
224
+ if self.InForeground and self._Canvas._ForegroundHTBitmap is None:
225
+ self._Canvas.MakeNewForegroundHTBitmap()
226
+ elif self._Canvas._HTBitmap is None:
227
+ self._Canvas.MakeNewHTBitmap()
228
+ if not self.HitColor:
229
+ if not self._Canvas.HitColorGenerator:
230
+ # first call to prevent the background color from being used.
231
+ self._Canvas.HitColorGenerator = _colorGenerator()
232
+ if six.PY3:
233
+ next(self._Canvas.HitColorGenerator)
234
+ else:
235
+ self._Canvas.HitColorGenerator.next()
236
+ if six.PY3:
237
+ self.HitColor = next(self._Canvas.HitColorGenerator)
238
+ else:
239
+ self.HitColor = self._Canvas.HitColorGenerator.next()
240
+ self.SetHitPen(self.HitColor,self.HitLineWidth)
241
+ self.SetHitBrush(self.HitColor)
242
+ # put the object in the hit dict, indexed by it's color
243
+ if not self._Canvas.HitDict:
244
+ self._Canvas.MakeHitDict()
245
+ self._Canvas.HitDict[Event][self.HitColor] = (self) # put the object in the hit dict, indexed by its color
246
+
247
+ def UnBindAll(self):
248
+ """
249
+ Unbind all events
250
+
251
+ .. note:: Currently only removes one from each list
252
+
253
+ """
254
+ ## fixme: this only removes one from each list, there could be more.
255
+ ## + patch by Tim Ansel
256
+ if self._Canvas.HitDict:
257
+ for Event in self._Canvas.HitDict.itervalues():
258
+ try:
259
+ del Event[self.HitColor]
260
+ except KeyError:
261
+ pass
262
+ self.HitAble = False
263
+
264
+
265
+ def SetBrush(self, FillColor, FillStyle):
266
+ """
267
+ Set the brush for this DrawObject
268
+
269
+ :param `FillColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
270
+ for valid entries
271
+ :param `FillStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetFillStyle`
272
+ for valid entries
273
+ """
274
+ if FillColor is None or FillStyle is None:
275
+ self.Brush = wx.TRANSPARENT_BRUSH
276
+ ##fixme: should I really re-set the style?
277
+ self.FillStyle = "Transparent"
278
+ else:
279
+ self.Brush = self.BrushList.setdefault(
280
+ (FillColor, FillStyle),
281
+ wx.Brush(FillColor, self.FillStyleList[FillStyle]))
282
+ #print("Setting Brush, BrushList length:", len(self.BrushList))
283
+
284
+ def SetPen(self, LineColor, LineStyle, LineWidth):
285
+ """
286
+ Set the Pen for this DrawObject
287
+
288
+ :param `LineColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
289
+ for valid entries
290
+ :param `LineStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineStyle`
291
+ for valid entries
292
+ :param integer `LineWidth`: the width in pixels
293
+ """
294
+ LineWidth = int(LineWidth)
295
+ if (LineColor is None) or (LineStyle is None):
296
+ self.Pen = wx.TRANSPARENT_PEN
297
+ self.LineStyle = 'Transparent'
298
+ else:
299
+ self.Pen = self.PenList.setdefault(
300
+ (LineColor, LineStyle, LineWidth),
301
+ wx.Pen(LineColor, LineWidth, self.LineStyleList[LineStyle]))
302
+
303
+ def SetHitBrush(self, HitColor):
304
+ """
305
+ Set the brush used for hit test, do not call directly.
306
+
307
+ :param `HitColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
308
+
309
+ """
310
+ if not self.HitFill:
311
+ self.HitBrush = wx.TRANSPARENT_BRUSH
312
+ else:
313
+ self.HitBrush = self.BrushList.setdefault(
314
+ (HitColor,"solid"),
315
+ wx.Brush(HitColor, self.FillStyleList["Solid"]))
316
+
317
+ def SetHitPen(self, HitColor, LineWidth):
318
+ """
319
+ Set the pen used for hit test, do not call directly.
320
+
321
+ :param `HitColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
322
+ :param integer `LineWidth`: the line width in pixels
323
+
324
+ """
325
+ if not self.HitLine:
326
+ self.HitPen = wx.TRANSPARENT_PEN
327
+ else:
328
+ self.HitPen = self.PenList.setdefault( (HitColor, "solid", self.HitLineWidth), wx.Pen(HitColor, self.HitLineWidth, self.LineStyleList["Solid"]) )
329
+
330
+ ## Just to make sure that they will always be there
331
+ ## the appropriate ones should be overridden in the subclasses
332
+ def SetColor(self, Color):
333
+ """
334
+ Set the Color - this method is overridden in the subclasses
335
+
336
+ :param `Color`: use one of the following values any valid entry from
337
+ :class:`wx.ColourDatabase`
338
+
339
+ - ``Green``
340
+ - ``White``
341
+ - ``Black``
342
+ - ``Grey``
343
+ - ``MediumGrey``
344
+ - ``LightGrey``
345
+ - ``Cyan``
346
+ - ``Red``
347
+
348
+ """
349
+
350
+ pass
351
+
352
+ def SetLineColor(self, LineColor):
353
+ """
354
+ Set the LineColor - this method is overridden in the subclasses
355
+
356
+ :param `LineColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
357
+ for valid values
358
+
359
+ """
360
+ pass
361
+
362
+ def SetLineStyle(self, LineStyle):
363
+ """
364
+ Set the LineStyle - this method is overridden in the subclasses
365
+
366
+ :param `LineStyle`: Use one of the following values or ``None`` :
367
+
368
+ ===================== =============================
369
+ Style Description
370
+ ===================== =============================
371
+ ``Solid`` Solid line
372
+ ``Transparent`` A transparent line
373
+ ``Dot`` Dotted line
374
+ ``LongDash`` Dashed line (long)
375
+ ``ShortDash`` Dashed line (short)
376
+ ``DotDash`` Dash-dot-dash line
377
+ ===================== =============================
378
+
379
+ """
380
+ pass
381
+
382
+ def SetLineWidth(self, LineWidth):
383
+ """
384
+ Set the LineWidth
385
+
386
+ :param integer `LineWidth`: sets the line width in pixel
387
+
388
+ """
389
+ pass
390
+
391
+ def SetFillColor(self, FillColor):
392
+ """
393
+ Set the FillColor - this method is overridden in the subclasses
394
+
395
+ :param `FillColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
396
+ for valid values
397
+
398
+ """
399
+ pass
400
+
401
+ def SetFillStyle(self, FillStyle):
402
+ """
403
+ Set the FillStyle - this method is overridden in the subclasses
404
+
405
+ :param string `FillStyle`: following is a list of valid values:
406
+
407
+ ===================== =========================================
408
+ Style Description
409
+ ===================== =========================================
410
+ ``Transparent`` Transparent fill
411
+ ``Solid`` Solid fill
412
+ ``BiDiagonalHatch`` Bi Diagonal hatch fill
413
+ ``CrossDiagHatch`` Cross Diagonal hatch fill
414
+ ``FDiagonal_Hatch`` F Diagonal hatch fill
415
+ ``CrossHatch`` Cross hatch fill
416
+ ``HorizontalHatch`` Horizontal hatch fill
417
+ ``VerticalHatch`` Vertical hatch fill
418
+ ===================== =========================================
419
+
420
+ """
421
+ pass
422
+
423
+ def PutInBackground(self):
424
+ """Put the object in the background."""
425
+ if self._Canvas and self.InForeground:
426
+ self._Canvas._ForeDrawList.remove(self)
427
+ self._Canvas._DrawList.append(self)
428
+ self._Canvas._BackgroundDirty = True
429
+ self.InForeground = False
430
+
431
+ def PutInForeground(self):
432
+ """Put the object in the foreground."""
433
+ if self._Canvas and (not self.InForeground):
434
+ self._Canvas._ForeDrawList.append(self)
435
+ self._Canvas._DrawList.remove(self)
436
+ self._Canvas._BackgroundDirty = True
437
+ self.InForeground = True
438
+
439
+ def Hide(self):
440
+ """Hide the object."""
441
+ self.Visible = False
442
+
443
+ def Show(self):
444
+ """Show the object."""
445
+ self.Visible = True
446
+
447
+
448
+ class ColorOnlyMixin:
449
+ """
450
+ Mixin class for objects that have just one color, rather than a fill
451
+ color and line color
452
+
453
+ """
454
+
455
+ def SetColor(self, Color):
456
+ """
457
+ Set the Color
458
+
459
+ :param `Color`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
460
+ for valid values
461
+
462
+ """
463
+ self.SetPen(Color,"Solid",1)
464
+ self.SetBrush(Color,"Solid")
465
+
466
+ SetFillColor = SetColor # Just to provide a consistant interface
467
+
468
+
469
+ class LineOnlyMixin:
470
+ """
471
+ Mixin class for objects that have just a line, rather than a fill
472
+ color and line color
473
+
474
+ """
475
+
476
+ def SetLineColor(self, LineColor):
477
+ """
478
+ Set the LineColor
479
+
480
+ :param `LineColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
481
+ for valid values
482
+
483
+ """
484
+ self.LineColor = LineColor
485
+ self.SetPen(LineColor,self.LineStyle,self.LineWidth)
486
+ SetColor = SetLineColor# so that it will do something reasonable
487
+
488
+ def SetLineStyle(self, LineStyle):
489
+ """
490
+ Set the LineStyle
491
+
492
+ :param `LineStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineStyle`
493
+ for valid values
494
+
495
+ """
496
+ self.LineStyle = LineStyle
497
+ self.SetPen(self.LineColor,LineStyle,self.LineWidth)
498
+
499
+ def SetLineWidth(self, LineWidth):
500
+ """
501
+ Set the LineWidth
502
+
503
+ :param integer `LineWidth`: line width in pixels
504
+
505
+ """
506
+ self.LineWidth = LineWidth
507
+ self.SetPen(self.LineColor,self.LineStyle,LineWidth)
508
+
509
+
510
+ class LineAndFillMixin(LineOnlyMixin):
511
+ """
512
+ Mixin class for objects that have both a line and a fill color and
513
+ style.
514
+
515
+ """
516
+ def SetFillColor(self, FillColor):
517
+ """
518
+ Set the FillColor
519
+
520
+ :param `FillColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
521
+ for valid values
522
+
523
+ """
524
+ self.FillColor = FillColor
525
+ self.SetBrush(FillColor, self.FillStyle)
526
+
527
+ def SetFillStyle(self, FillStyle):
528
+ """
529
+ Set the FillStyle
530
+
531
+ :param `FillStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetFillStyle`
532
+ for valid values
533
+
534
+ """
535
+ self.FillStyle = FillStyle
536
+ self.SetBrush(self.FillColor,FillStyle)
537
+
538
+ def SetUpDraw(self, dc, WorldToPixel, ScaleWorldToPixel, HTdc):
539
+ """
540
+ Setup for draw
541
+
542
+ :param `dc`: the dc to draw ???
543
+ :param `WorldToPixel`: ???
544
+ :param `ScaleWorldToPixel`: ???
545
+ :param `HTdc`: ???
546
+
547
+ """
548
+ dc.SetPen(self.Pen)
549
+ dc.SetBrush(self.Brush)
550
+ if HTdc and self.HitAble:
551
+ HTdc.SetPen(self.HitPen)
552
+ HTdc.SetBrush(self.HitBrush)
553
+ return ( WorldToPixel(self.XY),
554
+ ScaleWorldToPixel(self.WH) )
555
+
556
+
557
+ class XYObjectMixin:
558
+ """
559
+ This is a mixin class that provides some methods suitable for use
560
+ with objects that have a single (x,y) coordinate pair.
561
+ """
562
+
563
+ def Move(self, Delta):
564
+ """
565
+ Moves the object by delta, where delta is a (dx, dy) pair.
566
+
567
+ :param `Delta`: is a (dx, dy) pair ideally a `NumPy <http://www.numpy.org/>`_
568
+ array of shape (2, )
569
+
570
+ """
571
+ Delta = N.asarray(Delta, float)
572
+ self.XY += Delta
573
+ self.BoundingBox += Delta
574
+
575
+ if self._Canvas:
576
+ self._Canvas.BoundingBoxDirty = True
577
+
578
+ def CalcBoundingBox(self):
579
+ """Calculate the bounding box."""
580
+ ## This may get overwritten in some subclasses
581
+ self.BoundingBox = BBox.asBBox((self.XY, self.XY))
582
+
583
+ def SetPoint(self, xy):
584
+ xy = N.array(xy, float)
585
+ xy.shape = (2,)
586
+
587
+ self.XY = xy
588
+ self.CalcBoundingBox()
589
+
590
+ if self._Canvas:
591
+ self._Canvas.BoundingBoxDirty = True
592
+
593
+ class PointsObjectMixin:
594
+ """
595
+ A mixin class that provides some methods suitable for use
596
+ with objects that have a set of (x, y) coordinate pairs.
597
+
598
+ """
599
+
600
+ def Move(self, Delta):
601
+ """
602
+ Moves the object by delta, where delta is a (dx, dy) pair.
603
+
604
+ :param `Delta`: is a (dx, dy) pair ideally a `NumPy <http://www.numpy.org/>`_
605
+ array of shape (2, )
606
+
607
+ """
608
+ Delta = N.asarray(Delta, float)
609
+ Delta.shape = (2,)
610
+ self.Points += Delta
611
+ self.BoundingBox += Delta
612
+ if self._Canvas:
613
+ self._Canvas.BoundingBoxDirty = True
614
+
615
+ def CalcBoundingBox(self):
616
+ """Calculate the bounding box."""
617
+ self.BoundingBox = BBox.fromPoints(self.Points)
618
+ if self._Canvas:
619
+ self._Canvas.BoundingBoxDirty = True
620
+
621
+ def SetPoints(self, Points, copy=True):
622
+ """
623
+ Sets the coordinates of the points of the object to Points (NX2 array).
624
+
625
+ :param `Points`: takes a 2-tuple, or a (2,)
626
+ `NumPy <http://www.numpy.org/>`_ array of point coordinates
627
+ :param boolean `copy`: By default, a copy is made, if copy is set to
628
+ ``False``, a reference is used, if Points is a NumPy array of Floats.
629
+ This allows you to change some or all of the points without making
630
+ any copies.
631
+
632
+ For example::
633
+
634
+ Points = Object.Points
635
+ # shifts the points 5 in the x dir, and 10 in the y dir.
636
+ Points += (5, 10)
637
+ # Sets the points to the same array as it was
638
+ Object.SetPoints(Points, False)
639
+
640
+ """
641
+ if copy:
642
+ self.Points = N.array(Points, float)
643
+ self.Points.shape = (-1, 2) # Make sure it is a NX2 array, even if there is only one point
644
+ else:
645
+ self.Points = N.asarray(Points, float)
646
+ self.CalcBoundingBox()
647
+
648
+
649
+ class Polygon(PointsObjectMixin, LineAndFillMixin, DrawObject):
650
+ """
651
+ Draws a polygon
652
+
653
+ Points is a list of 2-tuples, or a NX2 NumPy array of
654
+ point coordinates. so that Points[N][0] is the x-coordinate of
655
+ point N and Points[N][1] is the y-coordinate or Points[N,0] is the
656
+ x-coordinate of point N and Points[N,1] is the y-coordinate for
657
+ arrays.
658
+
659
+ """
660
+ def __init__(self,
661
+ Points,
662
+ LineColor = "Black",
663
+ LineStyle = "Solid",
664
+ LineWidth = 1,
665
+ FillColor = None,
666
+ FillStyle = "Solid",
667
+ InForeground = False):
668
+ """
669
+ Default class constructor.
670
+
671
+ :param `Points`: start point, takes a 2-tuple, or a (2,)
672
+ `NumPy <http://www.numpy.org/>`_ array of point coordinates
673
+ :param `LineColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
674
+ :param `LineStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineStyle`
675
+ :param `LineWidth`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineWidth`
676
+ :param `FillColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
677
+ :param `FillStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetFillStyle`
678
+ :param boolean `InForeground`: should object be in foreground
679
+
680
+ """
681
+ DrawObject.__init__(self, InForeground)
682
+ self.Points = N.array(Points ,float) # this DOES need to make a copy
683
+ self.CalcBoundingBox()
684
+
685
+ self.LineColor = LineColor
686
+ self.LineStyle = LineStyle
687
+ self.LineWidth = LineWidth
688
+ self.FillColor = FillColor
689
+ self.FillStyle = FillStyle
690
+
691
+ self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)
692
+
693
+ self.SetPen(LineColor,LineStyle,LineWidth)
694
+ self.SetBrush(FillColor,FillStyle)
695
+
696
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel = None, HTdc=None):
697
+ Points = WorldToPixel(self.Points)#.tolist()
698
+ dc.SetPen(self.Pen)
699
+ dc.SetBrush(self.Brush)
700
+ dc.DrawPolygon(Points)
701
+ if HTdc and self.HitAble:
702
+ HTdc.SetPen(self.HitPen)
703
+ HTdc.SetBrush(self.HitBrush)
704
+ HTdc.DrawPolygon(Points)
705
+
706
+ class Line(PointsObjectMixin, LineOnlyMixin, DrawObject):
707
+ """
708
+ Draws a line
709
+
710
+ It will draw a straight line if there are two points, and a polyline
711
+ if there are more than two.
712
+
713
+ """
714
+ def __init__(self, Points,
715
+ LineColor = "Black",
716
+ LineStyle = "Solid",
717
+ LineWidth = 1,
718
+ InForeground = False):
719
+ """
720
+ Default class constructor.
721
+
722
+ :param `Points`: takes a 2-tuple, or a (2,)
723
+ `NumPy <http://www.numpy.org/>`_ array of point coordinates
724
+ :param `LineColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
725
+ :param `LineStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineStyle`
726
+ :param `LineWidth`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineWidth`
727
+ :param boolean `InForeground`: should object be in foreground
728
+
729
+ """
730
+ DrawObject.__init__(self, InForeground)
731
+
732
+
733
+ self.Points = N.array(Points,float)
734
+ self.CalcBoundingBox()
735
+
736
+ self.LineColor = LineColor
737
+ self.LineStyle = LineStyle
738
+ self.LineWidth = LineWidth
739
+
740
+ self.SetPen(LineColor,LineStyle,LineWidth)
741
+
742
+ self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)
743
+
744
+
745
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
746
+ Points = WorldToPixel(self.Points)
747
+ dc.SetPen(self.Pen)
748
+ dc.DrawLines(Points)
749
+ if HTdc and self.HitAble:
750
+ HTdc.SetPen(self.HitPen)
751
+ HTdc.DrawLines(Points)
752
+
753
+ class Spline(Line):
754
+ """Draws a spline"""
755
+ def __init__(self, *args, **kwargs):
756
+ """
757
+ Default class constructor.
758
+
759
+ see :class:`~lib.floatcanvas.FloatCanvas.Line`
760
+
761
+ """
762
+ Line.__init__(self, *args, **kwargs)
763
+
764
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
765
+ Points = WorldToPixel(self.Points)
766
+ dc.SetPen(self.Pen)
767
+ dc.DrawSpline(Points)
768
+ if HTdc and self.HitAble:
769
+ HTdc.SetPen(self.HitPen)
770
+ HTdc.DrawSpline(Points)
771
+
772
+
773
+ class Arrow(XYObjectMixin, LineOnlyMixin, DrawObject):
774
+ """
775
+ Draws an arrow
776
+
777
+ It will draw an arrow , starting at the point ``XY`` points at an angle
778
+ defined by ``Direction``.
779
+
780
+ """
781
+ def __init__(self,
782
+ XY,
783
+ Length,
784
+ Direction,
785
+ LineColor = "Black",
786
+ LineStyle = "Solid",
787
+ LineWidth = 2,
788
+ ArrowHeadSize = 8,
789
+ ArrowHeadAngle = 30,
790
+ InForeground = False):
791
+ """
792
+ Default class constructor.
793
+
794
+ :param `XY`: the (x, y) coordinate of the starting point, or a 2-tuple,
795
+ or a (2,) `NumPy <http://www.numpy.org/>`_ array
796
+ :param integer `Length`: length of arrow in pixels
797
+ :param integer `Direction`: angle of arrow in degrees, zero is straight
798
+ up `+` angle is to the right
799
+ :param `LineColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
800
+ :param `LineStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineStyle`
801
+ :param `LineWidth`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineWidth`
802
+ :param `ArrowHeadSize`: size of arrow head in pixels
803
+ :param `ArrowHeadAngle`: angle of arrow head in degrees
804
+ :param boolean `InForeground`: should object be in foreground
805
+
806
+ """
807
+
808
+ DrawObject.__init__(self, InForeground)
809
+
810
+ self.XY = N.array(XY, float)
811
+ self.XY.shape = (2,) # Make sure it is a length 2 vector
812
+ self.Length = Length
813
+ self.Direction = float(Direction)
814
+ self.ArrowHeadSize = ArrowHeadSize
815
+ self.ArrowHeadAngle = float(ArrowHeadAngle)
816
+
817
+ self.CalcArrowPoints()
818
+ self.CalcBoundingBox()
819
+
820
+ self.LineColor = LineColor
821
+ self.LineStyle = LineStyle
822
+ self.LineWidth = LineWidth
823
+
824
+ self.SetPen(LineColor,LineStyle,LineWidth)
825
+
826
+ ##fixme: How should the HitTest be drawn?
827
+ self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)
828
+
829
+ def SetDirection(self, Direction):
830
+ """
831
+ Set the direction
832
+
833
+ :param integer `Direction`: angle of arrow in degrees, zero is straight
834
+ up `+` angle is to the right
835
+
836
+ """
837
+ self.Direction = float(Direction)
838
+ self.CalcArrowPoints()
839
+
840
+ def SetLength(self, Length):
841
+ """
842
+ Set the length
843
+
844
+ :param integer `Length`: length of arrow in pixels
845
+
846
+ """
847
+ self.Length = Length
848
+ self.CalcArrowPoints()
849
+
850
+ def SetLengthDirection(self, Length, Direction):
851
+ """
852
+ Set the lenght and direction
853
+
854
+ :param integer `Length`: length of arrow in pixels
855
+ :param integer `Direction`: angle of arrow in degrees, zero is straight
856
+ up `+` angle is to the right
857
+
858
+ """
859
+ self.Direction = float(Direction)
860
+ self.Length = Length
861
+ self.CalcArrowPoints()
862
+
863
+ ## def CalcArrowPoints(self):
864
+ ## L = self.Length
865
+ ## S = self.ArrowHeadSize
866
+ ## phi = self.ArrowHeadAngle * N.pi / 360
867
+ ## theta = (self.Direction-90.0) * N.pi / 180
868
+ ## ArrowPoints = N.array( ( (0, L, L - S*N.cos(phi),L, L - S*N.cos(phi) ),
869
+ ## (0, 0, S*N.sin(phi), 0, -S*N.sin(phi) ) ),
870
+ ## float)
871
+ ## RotationMatrix = N.array( ( ( N.cos(theta), -N.sin(theta) ),
872
+ ## ( N.sin(theta), N.cos(theta) ) ),
873
+ ## N.float
874
+ ## )
875
+ ## ArrowPoints = N.matrixmultiply(RotationMatrix, ArrowPoints)
876
+ ## self.ArrowPoints = N.transpose(ArrowPoints)
877
+
878
+ def CalcArrowPoints(self):
879
+ """Calculate the arrow points."""
880
+ L = self.Length
881
+ S = self.ArrowHeadSize
882
+ phi = self.ArrowHeadAngle * N.pi / 360
883
+ theta = (270 - self.Direction) * N.pi / 180
884
+ AP = N.array( ( (0,0),
885
+ (0,0),
886
+ (N.cos(theta - phi), -N.sin(theta - phi) ),
887
+ (0,0),
888
+ (N.cos(theta + phi), -N.sin(theta + phi) ),
889
+ ), float)
890
+ AP *= S
891
+ shift = (-L*N.cos(theta), L*N.sin(theta) )
892
+ AP[1:,:] += shift
893
+ self.ArrowPoints = AP
894
+
895
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
896
+ dc.SetPen(self.Pen)
897
+ xy = WorldToPixel(self.XY)
898
+ ArrowPoints = xy + self.ArrowPoints
899
+ dc.DrawLines(ArrowPoints)
900
+ if HTdc and self.HitAble:
901
+ HTdc.SetPen(self.HitPen)
902
+ HTdc.DrawLines(ArrowPoints)
903
+
904
+
905
+ class ArrowLine(PointsObjectMixin, LineOnlyMixin, DrawObject):
906
+ """
907
+ Draws an arrow line.
908
+
909
+ It will draw a set of arrows from point to point.
910
+
911
+ It takes a list of 2-tuples, or a NX2 NumPy Float array of point coordinates.
912
+
913
+ """
914
+
915
+ def __init__(self,
916
+ Points,
917
+ LineColor = "Black",
918
+ LineStyle = "Solid",
919
+ LineWidth = 1,
920
+ ArrowHeadSize = 8,
921
+ ArrowHeadAngle = 30,
922
+ InForeground = False):
923
+ """
924
+ Default class constructor.
925
+
926
+ :param `Points`: takes a 2-tuple, or a (2,)
927
+ `NumPy <http://www.numpy.org/>`_ array of point coordinates
928
+ :param `LineColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
929
+ :param `LineStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineStyle`
930
+ :param `LineWidth`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineWidth`
931
+ :param `ArrowHeadSize`: size of arrow head in pixels
932
+ :param `ArrowHeadAngle`: angle of arrow head in degrees
933
+ :param boolean `InForeground`: should object be in foreground
934
+
935
+ """
936
+
937
+ DrawObject.__init__(self, InForeground)
938
+
939
+ self.Points = N.asarray(Points,float)
940
+ self.Points.shape = (-1,2) # Make sure it is a NX2 array, even if there is only one point
941
+ self.ArrowHeadSize = ArrowHeadSize
942
+ self.ArrowHeadAngle = float(ArrowHeadAngle)
943
+
944
+ self.CalcArrowPoints()
945
+ self.CalcBoundingBox()
946
+
947
+ self.LineColor = LineColor
948
+ self.LineStyle = LineStyle
949
+ self.LineWidth = LineWidth
950
+
951
+ self.SetPen(LineColor,LineStyle,LineWidth)
952
+
953
+ self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)
954
+
955
+ def CalcArrowPoints(self):
956
+ """Calculate the arrow points."""
957
+ S = self.ArrowHeadSize
958
+ phi = self.ArrowHeadAngle * N.pi / 360
959
+ Points = self.Points
960
+ n = Points.shape[0]
961
+ self.ArrowPoints = N.zeros((n-1, 3, 2), float)
962
+ for i in range(n-1):
963
+ dx, dy = self.Points[i] - self.Points[i+1]
964
+ theta = N.arctan2(dy, dx)
965
+ AP = N.array( (
966
+ (N.cos(theta - phi), -N.sin(theta-phi)),
967
+ (0,0),
968
+ (N.cos(theta + phi), -N.sin(theta + phi))
969
+ ),
970
+ float)
971
+ self.ArrowPoints[i,:,:] = AP
972
+ self.ArrowPoints *= S
973
+
974
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
975
+ Points = WorldToPixel(self.Points)
976
+ ArrowPoints = Points[1:,N.newaxis,:] + self.ArrowPoints
977
+ dc.SetPen(self.Pen)
978
+ dc.DrawLines(Points)
979
+ for arrow in ArrowPoints:
980
+ dc.DrawLines(arrow)
981
+ if HTdc and self.HitAble:
982
+ HTdc.SetPen(self.HitPen)
983
+ HTdc.DrawLines(Points)
984
+ for arrow in ArrowPoints:
985
+ HTdc.DrawLines(arrow)
986
+
987
+
988
+ class PointSet(PointsObjectMixin, ColorOnlyMixin, DrawObject):
989
+ """
990
+ Draws a set of points
991
+
992
+ If Points is a sequence of tuples: Points[N][0] is the x-coordinate of
993
+ point N and Points[N][1] is the y-coordinate.
994
+
995
+ If Points is a NumPy array: Points[N,0] is the x-coordinate of point
996
+ N and Points[N,1] is the y-coordinate for arrays.
997
+
998
+ Each point will be drawn the same color and Diameter. The Diameter
999
+ is in screen pixels, not world coordinates.
1000
+
1001
+ The hit-test code does not distingish between the points, you will
1002
+ only know that one of the points got hit, not which one. You can use
1003
+ PointSet.FindClosestPoint(WorldPoint) to find out which one
1004
+
1005
+ In the case of points, the HitLineWidth is used as diameter.
1006
+
1007
+ """
1008
+ def __init__(self, Points, Color="Black", Diameter=1, InForeground=False):
1009
+ """
1010
+ Default class constructor.
1011
+
1012
+ :param `Points`: takes a 2-tuple, or a (2,)
1013
+ `NumPy <http://www.numpy.org/>`_ array of point coordinates
1014
+ :param `Color`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
1015
+ :param integer `Diameter`: the points diameter
1016
+ :param boolean `InForeground`: should object be in foreground
1017
+
1018
+ """
1019
+ DrawObject.__init__(self, InForeground)
1020
+
1021
+ self.Points = N.array(Points,float)
1022
+ self.Points.shape = (-1,2) # Make sure it is a NX2 array, even if there is only one point
1023
+ self.CalcBoundingBox()
1024
+ self.Diameter = Diameter
1025
+
1026
+ self.HitLineWidth = min(self.MinHitLineWidth, Diameter)
1027
+ self.SetColor(Color)
1028
+
1029
+ def SetDiameter(self, Diameter):
1030
+ """
1031
+ Sets the diameter
1032
+
1033
+ :param integer `Diameter`: the points diameter
1034
+
1035
+ """
1036
+ self.Diameter = Diameter
1037
+
1038
+ def FindClosestPoint(self, XY):
1039
+ """
1040
+ Returns the index of the closest point to the point, XY, given
1041
+ in World coordinates. It's essentially random which you get if
1042
+ there are more than one that are the same.
1043
+
1044
+ This can be used to figure out which point got hit in a mouse
1045
+ binding callback, for instance. It's a lot faster that using a
1046
+ lot of separate points.
1047
+
1048
+ :param `XY`: the (x,y) coordinates of the point to look for, it takes a
1049
+ 2-tuple or (2,) numpy array in World coordinates
1050
+
1051
+ """
1052
+ d = self.Points - XY
1053
+ return N.argmin(N.hypot(d[:,0],d[:,1]))
1054
+
1055
+
1056
+ def DrawD2(self, dc, Points):
1057
+ # A Little optimization for a diameter2 - point
1058
+ dc.DrawPointList(Points)
1059
+ dc.DrawPointList(Points + (1,0))
1060
+ dc.DrawPointList(Points + (0,1))
1061
+ dc.DrawPointList(Points + (1,1))
1062
+
1063
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
1064
+ dc.SetPen(self.Pen)
1065
+ Points = WorldToPixel(self.Points)
1066
+ if self.Diameter <= 1:
1067
+ dc.DrawPointList(Points)
1068
+ elif self.Diameter <= 2:
1069
+ self.DrawD2(dc, Points)
1070
+ else:
1071
+ dc.SetBrush(self.Brush)
1072
+ radius = int(round(self.Diameter/2))
1073
+ ##fixme: I really should add a DrawCircleList to wxPython
1074
+ if len(Points) > 100:
1075
+ xy = Points
1076
+ xywh = N.concatenate((xy-radius, N.ones(xy.shape) * self.Diameter ), 1 )
1077
+ dc.DrawEllipseList(xywh)
1078
+ else:
1079
+ for xy in Points:
1080
+ dc.DrawCircle(xy[0],xy[1], radius)
1081
+ if HTdc and self.HitAble:
1082
+ HTdc.SetPen(self.HitPen)
1083
+ HTdc.SetBrush(self.HitBrush)
1084
+ if self.Diameter <= 1:
1085
+ HTdc.DrawPointList(Points)
1086
+ elif self.Diameter <= 2:
1087
+ self.DrawD2(HTdc, Points)
1088
+ else:
1089
+ if len(Points) > 100:
1090
+ xy = Points
1091
+ xywh = N.concatenate((xy-radius, N.ones(xy.shape) * self.Diameter ), 1 )
1092
+ HTdc.DrawEllipseList(xywh)
1093
+ else:
1094
+ for xy in Points:
1095
+ HTdc.DrawCircle(xy[0],xy[1], radius)
1096
+
1097
+ class Point(XYObjectMixin, ColorOnlyMixin, DrawObject):
1098
+ """
1099
+ A point DrawObject
1100
+
1101
+ .. note::
1102
+
1103
+ The Bounding box is just the point, and doesn't include the Diameter.
1104
+
1105
+ The HitLineWidth is used as diameter for the Hit Test.
1106
+
1107
+ """
1108
+ def __init__(self, XY, Color="Black", Diameter=1, InForeground=False):
1109
+ """
1110
+ Default class constructor.
1111
+
1112
+ :param `XY`: the (x, y) coordinate of the center of the point, or a
1113
+ 2-tuple, or a (2,) `NumPy <http://www.numpy.org/>`_ array
1114
+ :param `Color`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
1115
+ :param integer `Diameter`: in screen points
1116
+ :param `InForeground`: define if object is in foreground
1117
+
1118
+ """
1119
+
1120
+ DrawObject.__init__(self, InForeground)
1121
+
1122
+ self.XY = N.array(XY, float)
1123
+ self.XY.shape = (2,) # Make sure it is a length 2 vector
1124
+ self.CalcBoundingBox()
1125
+ self.SetColor(Color)
1126
+ self.Diameter = Diameter
1127
+
1128
+ self.HitLineWidth = self.MinHitLineWidth
1129
+
1130
+ def SetDiameter(self, Diameter):
1131
+ """
1132
+ Set the diameter of the object.
1133
+
1134
+ :param integer `Diameter`: in screen points
1135
+
1136
+ """
1137
+ self.Diameter = Diameter
1138
+
1139
+ def _Draw(self, dc, WorldToPixel, ScaleWorldToPixel, HTdc=None):
1140
+ dc.SetPen(self.Pen)
1141
+ xy = WorldToPixel(self.XY)
1142
+ if self.Diameter <= 1:
1143
+ dc.DrawPoint(xy[0], xy[1])
1144
+ else:
1145
+ dc.SetBrush(self.Brush)
1146
+ radius = int(round(self.Diameter/2))
1147
+ dc.DrawCircle(xy[0],xy[1], radius)
1148
+ if HTdc and self.HitAble:
1149
+ HTdc.SetPen(self.HitPen)
1150
+ if self.Diameter <= 1:
1151
+ HTdc.DrawPoint(xy[0], xy[1])
1152
+ else:
1153
+ HTdc.SetBrush(self.HitBrush)
1154
+ HTdc.DrawCircle(xy[0],xy[1], radius)
1155
+
1156
+ class SquarePoint(XYObjectMixin, ColorOnlyMixin, DrawObject):
1157
+ """
1158
+ Draws a square point
1159
+
1160
+ The Size is in screen points, not world coordinates, so the
1161
+ Bounding box is just the point, and doesn't include the Size.
1162
+
1163
+ The HitLineWidth is used as diameter for the Hit Test.
1164
+
1165
+ """
1166
+ def __init__(self, Point, Color="Black", Size=4, InForeground=False):
1167
+ """
1168
+ Default class constructor.
1169
+
1170
+ :param `Point`: takes a 2-tuple, or a (2,)
1171
+ `NumPy <http://www.numpy.org/>`_ array of point coordinates
1172
+ :param `Color`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
1173
+ :param integer `Size`: the size of the square point
1174
+ :param boolean `InForeground`: should object be in foreground
1175
+
1176
+ """
1177
+ DrawObject.__init__(self, InForeground)
1178
+
1179
+ self.XY = N.array(Point, float)
1180
+ self.XY.shape = (2,) # Make sure it is a length 2 vector
1181
+ self.CalcBoundingBox()
1182
+ self.SetColor(Color)
1183
+ self.Size = Size
1184
+
1185
+ self.HitLineWidth = self.MinHitLineWidth
1186
+
1187
+ def SetSize(self, Size):
1188
+ """
1189
+ Sets the size
1190
+
1191
+ :param integer `Size`: the size of the square point
1192
+
1193
+ """
1194
+ self.Size = Size
1195
+
1196
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
1197
+ Size = self.Size
1198
+ dc.SetPen(self.Pen)
1199
+ xc,yc = WorldToPixel(self.XY)
1200
+
1201
+ if self.Size <= 1:
1202
+ dc.DrawPoint(xc, yc)
1203
+ else:
1204
+ x = xc - Size // 2
1205
+ y = yc - Size // 2
1206
+ dc.SetBrush(self.Brush)
1207
+ dc.DrawRectangle(x, y, Size, Size)
1208
+ if HTdc and self.HitAble:
1209
+ HTdc.SetPen(self.HitPen)
1210
+ if self.Size <= 1:
1211
+ HTdc.DrawPoint(xc, xc)
1212
+ else:
1213
+ HTdc.SetBrush(self.HitBrush)
1214
+ HTdc.DrawRectangle(x, y, Size, Size)
1215
+
1216
+ class RectEllipse(XYObjectMixin, LineAndFillMixin, DrawObject):
1217
+ """A RectEllipse draw object."""
1218
+ def __init__(self, XY, WH,
1219
+ LineColor = "Black",
1220
+ LineStyle = "Solid",
1221
+ LineWidth = 1,
1222
+ FillColor = None,
1223
+ FillStyle = "Solid",
1224
+ InForeground = False):
1225
+ """
1226
+ Default class constructor.
1227
+
1228
+ :param `XY`: the (x, y) coordinate of the corner of RectEllipse, or a 2-tuple,
1229
+ or a (2,) `NumPy <http://www.numpy.org/>`_ array
1230
+ :param `WH`: a tuple with the Width and Height for the object
1231
+ :param `LineColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
1232
+ :param `LineStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineStyle`
1233
+ :param `LineWidth`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineWidth`
1234
+ :param `FillColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
1235
+ :param `FillStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetFillStyle`
1236
+ :param `InForeground`: put object in foreground
1237
+
1238
+ """
1239
+
1240
+ DrawObject.__init__(self,InForeground)
1241
+
1242
+ self.SetShape(XY, WH)
1243
+ self.LineColor = LineColor
1244
+ self.LineStyle = LineStyle
1245
+ self.LineWidth = LineWidth
1246
+ self.FillColor = FillColor
1247
+ self.FillStyle = FillStyle
1248
+
1249
+ self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)
1250
+
1251
+ # these define the behaviour when zooming makes the objects really small.
1252
+ self.MinSize = 1
1253
+ self.DisappearWhenSmall = True
1254
+
1255
+ self.SetPen(LineColor,LineStyle,LineWidth)
1256
+ self.SetBrush(FillColor,FillStyle)
1257
+
1258
+ def SetShape(self, XY, WH):
1259
+ """
1260
+ Set the shape of the object.
1261
+
1262
+ :param `XY`: takes a 2-tuple, or a (2,) `NumPy <http://www.numpy.org/>`_
1263
+ array of point coordinates
1264
+ :param `WH`: a tuple with the Width and Height for the object
1265
+
1266
+ """
1267
+ self.XY = N.array( XY, float)
1268
+ self.XY.shape = (2,)
1269
+ self.WH = N.array( WH, float)
1270
+ self.WH.shape = (2,)
1271
+ self.CalcBoundingBox()
1272
+
1273
+ def CalcBoundingBox(self):
1274
+ """Calculate the bounding box."""
1275
+ # you need this in case Width or Height are negative
1276
+ corners = N.array((self.XY, (self.XY + self.WH) ), float)
1277
+ self.BoundingBox = BBox.fromPoints(corners)
1278
+ if self._Canvas:
1279
+ self._Canvas.BoundingBoxDirty = True
1280
+
1281
+
1282
+ class Rectangle(RectEllipse):
1283
+ """Draws a rectangle see :class:`~lib.floatcanvas.FloatCanvas.RectEllipse`"""
1284
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
1285
+ ( XY, WH ) = self.SetUpDraw(dc,
1286
+ WorldToPixel,
1287
+ ScaleWorldToPixel,
1288
+ HTdc)
1289
+ WH[N.abs(WH) < self.MinSize] = self.MinSize
1290
+ if not( self.DisappearWhenSmall and N.abs(WH).min() <= self.MinSize) : # don't try to draw it too tiny
1291
+ dc.DrawRectangle(XY, WH)
1292
+ if HTdc and self.HitAble:
1293
+ HTdc.DrawRectangle(XY, WH)
1294
+
1295
+
1296
+ class Ellipse(RectEllipse):
1297
+ """Draws an ellipse see :class:`~lib.floatcanvas.FloatCanvas.RectEllipse`"""
1298
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
1299
+ ( XY, WH ) = self.SetUpDraw(dc,
1300
+ WorldToPixel,
1301
+ ScaleWorldToPixel,
1302
+ HTdc)
1303
+ WH[N.abs(WH) < self.MinSize] = self.MinSize
1304
+ if not( self.DisappearWhenSmall and N.abs(WH).min() <= self.MinSize) : # don't try to draw it too tiny
1305
+ dc.DrawEllipse(XY, WH)
1306
+ if HTdc and self.HitAble:
1307
+ HTdc.DrawEllipse(XY, WH)
1308
+
1309
+ class Circle(XYObjectMixin, LineAndFillMixin, DrawObject):
1310
+ """Draws a circle"""
1311
+ def __init__(self, XY, Diameter,
1312
+ LineColor = "Black",
1313
+ LineStyle = "Solid",
1314
+ LineWidth = 1,
1315
+ FillColor = None,
1316
+ FillStyle = "Solid",
1317
+ InForeground = False):
1318
+ """
1319
+ Default class constructor.
1320
+
1321
+ :param `XY`: the (x, y) coordinate of the center of the circle, or a 2-tuple,
1322
+ or a (2,) `NumPy <http://www.numpy.org/>`_ array
1323
+ :param integer `Diameter`: the diameter for the object
1324
+ :param `LineColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
1325
+ :param `LineStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineStyle`
1326
+ :param `LineWidth`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineWidth`
1327
+ :param `FillColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
1328
+ :param `FillStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetFillStyle`
1329
+ :param boolean `InForeground`: should object be in foreground
1330
+
1331
+ """
1332
+ DrawObject.__init__(self, InForeground)
1333
+
1334
+ self.XY = N.array(XY, float)
1335
+ self.WH = N.array((Diameter/2, Diameter/2), float) # just to keep it compatible with others
1336
+ self.CalcBoundingBox()
1337
+
1338
+ self.LineColor = LineColor
1339
+ self.LineStyle = LineStyle
1340
+ self.LineWidth = LineWidth
1341
+ self.FillColor = FillColor
1342
+ self.FillStyle = FillStyle
1343
+
1344
+ self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)
1345
+
1346
+ # these define the behaviour when zooming makes the objects really small.
1347
+ self.MinSize = 1
1348
+ self.DisappearWhenSmall = True
1349
+
1350
+ self.SetPen(LineColor,LineStyle,LineWidth)
1351
+ self.SetBrush(FillColor,FillStyle)
1352
+
1353
+ def SetDiameter(self, Diameter):
1354
+ """
1355
+ Set the diameter of the object
1356
+
1357
+ :param integer `Diameter`: the diameter for the object
1358
+
1359
+ """
1360
+ self.WH = N.array((Diameter/2, Diameter/2), float) # just to keep it compatible with others
1361
+
1362
+ def CalcBoundingBox(self):
1363
+ """Calculate the bounding box of the object."""
1364
+ # you need this in case Width or Height are negative
1365
+ self.BoundingBox = BBox.fromPoints( (self.XY+self.WH, self.XY-self.WH) )
1366
+ if self._Canvas:
1367
+ self._Canvas.BoundingBoxDirty = True
1368
+
1369
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
1370
+ ( XY, WH ) = self.SetUpDraw(dc,
1371
+ WorldToPixel,
1372
+ ScaleWorldToPixel,
1373
+ HTdc)
1374
+
1375
+ WH[N.abs(WH) < self.MinSize] = self.MinSize
1376
+ if not( self.DisappearWhenSmall and N.abs(WH).min() <= self.MinSize) : # don't try to draw it too tiny
1377
+ dc.DrawCircle(XY, WH[0])
1378
+ if HTdc and self.HitAble:
1379
+ HTdc.DrawCircle(XY, WH[0])
1380
+
1381
+
1382
+ class TextObjectMixin(XYObjectMixin):
1383
+ """
1384
+ A mix in class that holds attributes and methods that are needed by
1385
+ the Text objects
1386
+
1387
+ """
1388
+
1389
+ ## I'm caching fonts, because on GTK, getting a new font can take a
1390
+ ## while. However, it gets cleared after every full draw as hanging
1391
+ ## on to a bunch of large fonts takes a massive amount of memory.
1392
+
1393
+ FontList = {}
1394
+
1395
+ LayoutFontSize = 16 # font size used for calculating layout
1396
+
1397
+ def SetFont(self, Size, Family, Style, Weight, Underlined, FaceName):
1398
+ self.Font = self.FontList.setdefault( (Size,
1399
+ Family,
1400
+ Style,
1401
+ Weight,
1402
+ Underlined,
1403
+ FaceName),
1404
+ #wx.FontFromPixelSize((0.45*Size,Size), # this seemed to give a decent height/width ratio on Windows
1405
+ wx.Font(Size,
1406
+ Family,
1407
+ Style,
1408
+ Weight,
1409
+ Underlined,
1410
+ FaceName) )
1411
+
1412
+ def SetColor(self, Color):
1413
+ self.Color = Color
1414
+
1415
+ def SetBackgroundColor(self, BackgroundColor):
1416
+ self.BackgroundColor = BackgroundColor
1417
+
1418
+ def SetText(self, String):
1419
+ """
1420
+ Re-sets the text displayed by the object
1421
+
1422
+ In the case of the ScaledTextBox, it will re-do the layout as appropriate
1423
+
1424
+ Note: only tested with the ScaledTextBox
1425
+
1426
+ """
1427
+
1428
+ self.String = String
1429
+ self.LayoutText()
1430
+
1431
+ def LayoutText(self):
1432
+ """
1433
+ A dummy method to re-do the layout of the text.
1434
+
1435
+ A derived object needs to override this if required.
1436
+
1437
+ """
1438
+ pass
1439
+
1440
+ ## store the function that shift the coords for drawing text. The
1441
+ ## "c" parameter is the correction for world coordinates, rather
1442
+ ## than pixel coords as the y axis is reversed
1443
+ ## pad is the extra space around the text
1444
+ ## if world = 1, the vertical shift is done in y-up coordinates
1445
+ ShiftFunDict = {'tl': lambda x, y, w, h, world=0, pad=0: (x + pad, y + pad - 2*world*pad),
1446
+ 'tc': lambda x, y, w, h, world=0, pad=0: (x - w/2, y + pad - 2*world*pad),
1447
+ 'tr': lambda x, y, w, h, world=0, pad=0: (x - w - pad, y + pad - 2*world*pad),
1448
+ 'cl': lambda x, y, w, h, world=0, pad=0: (x + pad, y - h/2 + world*h),
1449
+ 'cc': lambda x, y, w, h, world=0, pad=0: (x - w/2, y - h/2 + world*h),
1450
+ 'cr': lambda x, y, w, h, world=0, pad=0: (x - w - pad, y - h/2 + world*h),
1451
+ 'bl': lambda x, y, w, h, world=0, pad=0: (x + pad, y - h + 2*world*h - pad + world*2*pad) ,
1452
+ 'bc': lambda x, y, w, h, world=0, pad=0: (x - w/2, y - h + 2*world*h - pad + world*2*pad) ,
1453
+ 'br': lambda x, y, w, h, world=0, pad=0: (x - w - pad, y - h + 2*world*h - pad + world*2*pad)}
1454
+
1455
+ class Text(TextObjectMixin, DrawObject):
1456
+ """
1457
+ Draws a text object
1458
+
1459
+ The size is fixed, and does not scale with the drawing.
1460
+
1461
+ The hit-test is done on the entire text extent
1462
+
1463
+ """
1464
+
1465
+ def __init__(self, String, xy,
1466
+ Size = 14,
1467
+ Color = "Black",
1468
+ BackgroundColor = None,
1469
+ Family = wx.FONTFAMILY_MODERN,
1470
+ Style = wx.FONTSTYLE_NORMAL,
1471
+ Weight = wx.FONTWEIGHT_NORMAL,
1472
+ Underlined = False,
1473
+ Position = 'tl',
1474
+ InForeground = False,
1475
+ Font = None):
1476
+ """
1477
+ Default class constructor.
1478
+
1479
+ :param string `string`: the text to draw
1480
+ :param `XY`: the (x, y) coordinate of the corner of the text, or a 2-tuple,
1481
+ or a (2,) `NumPy <http://www.numpy.org/>`_ array
1482
+ :param `Size`: the font size
1483
+ :param `Color`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
1484
+ :param `BackgroundColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
1485
+ :param wx.FontFamily `Family`: a valid :ref:`wx.FontFamily`
1486
+ :param wx.FontStyle `Style`: a valid :ref:`wx.FontStyle`
1487
+ :param wx.FontWeight `Weight`: a valid :ref:`wx.FontWeight`
1488
+ :param boolean `Underlined`: underline the text
1489
+ :param string `Position`: a two character string indicating where in
1490
+ relation to the coordinates the box should be oriented
1491
+ :param boolean `InForeground`: should object be in foreground
1492
+ :param wx.Font `Font`: alternatively you can define :ref:`wx.Font` and the
1493
+ above will be ignored.
1494
+
1495
+ ============== ==========================
1496
+ 1st character Meaning
1497
+ ============== ==========================
1498
+ ``t`` top
1499
+ ``c`` center
1500
+ ``b`` bottom
1501
+ ============== ==========================
1502
+
1503
+ ============== ==========================
1504
+ 2nd character Meaning
1505
+ ============== ==========================
1506
+ ``l`` left
1507
+ ``c`` center
1508
+ ``r`` right
1509
+ ============== ==========================
1510
+
1511
+ :param wx.Font `Font`: a valid :class:`wx.Font`
1512
+ :param boolean `InForeground`: should object be in foreground
1513
+
1514
+ """
1515
+ DrawObject.__init__(self,InForeground)
1516
+
1517
+ self.String = String
1518
+ # Input size in in Pixels, compute points size from FontScaleinfo.
1519
+ # fixme: for printing, we'll have to do something a little different
1520
+ self.Size = Size * FontScale
1521
+
1522
+ self.Color = Color
1523
+ self.BackgroundColor = BackgroundColor
1524
+
1525
+ if not Font:
1526
+ FaceName = ''
1527
+ else:
1528
+ FaceName = Font.GetFaceName()
1529
+ Family = Font.GetFamily()
1530
+ Size = Font.GetPointSize()
1531
+ Style = Font.GetStyle()
1532
+ Underlined = Font.GetUnderlined()
1533
+ Weight = Font.GetWeight()
1534
+ self.SetFont(Size, Family, Style, Weight, Underlined, FaceName)
1535
+
1536
+ self.BoundingBox = BBox.asBBox((xy, xy))
1537
+
1538
+ self.XY = N.asarray(xy)
1539
+ self.XY.shape = (2,)
1540
+
1541
+ (self.TextWidth, self.TextHeight) = (None, None)
1542
+ self.ShiftFun = self.ShiftFunDict[Position]
1543
+
1544
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
1545
+ XY = WorldToPixel(self.XY)
1546
+ dc.SetFont(self.Font)
1547
+ dc.SetTextForeground(self.Color)
1548
+ if self.BackgroundColor:
1549
+ dc.SetBackgroundMode(wx.SOLID)
1550
+ dc.SetTextBackground(self.BackgroundColor)
1551
+ else:
1552
+ dc.SetBackgroundMode(wx.TRANSPARENT)
1553
+ if self.TextWidth is None or self.TextHeight is None:
1554
+ (self.TextWidth, self.TextHeight) = dc.GetTextExtent(self.String)
1555
+ XY = self.ShiftFun(XY[0], XY[1], self.TextWidth, self.TextHeight)
1556
+ dc.DrawText(self.String, XY)
1557
+ if HTdc and self.HitAble:
1558
+ HTdc.SetPen(self.HitPen)
1559
+ HTdc.SetBrush(self.HitBrush)
1560
+ HTdc.DrawRectangle(XY, (self.TextWidth, self.TextHeight) )
1561
+
1562
+ class ScaledText(TextObjectMixin, DrawObject):
1563
+ """
1564
+ ##fixme: this can be depricated and jsut use ScaledTextBox with different defaults.
1565
+
1566
+ This class creates a text object that is scaled when zoomed. It is
1567
+ placed at the coordinates, x,y. the "Position" argument is a two
1568
+ charactor string, indicating where in relation to the coordinates
1569
+ the string should be oriented.
1570
+
1571
+ The first letter is: t, c, or b, for top, center and bottom The
1572
+ second letter is: l, c, or r, for left, center and right The
1573
+ position refers to the position relative to the text itself. It
1574
+ defaults to "tl" (top left).
1575
+
1576
+ Size is the size of the font in world coordinates.
1577
+
1578
+ * Family: Font family, a generic way of referring to fonts without
1579
+ specifying actual facename. One of:
1580
+
1581
+ * wx.FONTFAMILY_DEFAULT: Chooses a default font.
1582
+ * wx.FONTFAMILY_DECORATIVE: A decorative font.
1583
+ * wx.FONTFAMILY_ROMAN: A formal, serif font.
1584
+ * wx.FONTFAMILY_SCRIPT: A handwriting font.
1585
+ * wx.FONTFAMILY_SWISS: A sans-serif font.
1586
+ * wx.FONTFAMILY_MODERN: A fixed pitch font.
1587
+
1588
+ .. note:: these are only as good as the wxWindows defaults, which aren't so good.
1589
+
1590
+ * Style: One of wx.FONTSTYLE_NORMAL, wx.FONTSTYLE_SLANT and wx.FONTSTYLE_ITALIC.
1591
+ * Weight: One of wx.FONTWEIGHT_NORMAL, wx.FONTWEIGHT_LIGHT and wx.FONTWEIGHT_BOLD.
1592
+ * Underlined: The value can be True or False. At present this may have an an
1593
+ effect on Windows only.
1594
+
1595
+
1596
+ Alternatively, you can set the kw arg: Font, to a wx.Font, and the
1597
+ above will be ignored. The size of the font you specify will be
1598
+ ignored, but the rest of its attributes will be preserved.
1599
+
1600
+ The size will scale as the drawing is zoomed.
1601
+
1602
+ Bugs/Limitations:
1603
+
1604
+ As fonts are scaled, the do end up a little different, so you don't
1605
+ get exactly the same picture as you scale up and doen, but it's
1606
+ pretty darn close.
1607
+
1608
+ On wxGTK1 on my Linux system, at least, using a font of over about
1609
+ 3000 pts. brings the system to a halt. It's the Font Server using
1610
+ huge amounts of memory. My work around is to max the font size to
1611
+ 3000 points, so it won't scale past there. GTK2 uses smarter font
1612
+ drawing, so that may not be an issue in future versions, so feel
1613
+ free to test. Another smarter way to do it would be to set a global
1614
+ zoom limit at that point.
1615
+
1616
+ The hit-test is done on the entire text extent. This could be made
1617
+ optional, but I haven't gotten around to it.
1618
+
1619
+ """
1620
+
1621
+ def __init__(self,
1622
+ String,
1623
+ XY,
1624
+ Size,
1625
+ Color = "Black",
1626
+ BackgroundColor = None,
1627
+ Family = wx.FONTFAMILY_MODERN,
1628
+ Style = wx.FONTSTYLE_NORMAL,
1629
+ Weight = wx.FONTWEIGHT_NORMAL,
1630
+ Underlined = False,
1631
+ Position = 'tl',
1632
+ Font = None,
1633
+ InForeground = False):
1634
+
1635
+ DrawObject.__init__(self,InForeground)
1636
+
1637
+ self.String = String
1638
+ self.XY = N.array( XY, float)
1639
+ self.XY.shape = (2,)
1640
+ self.Size = Size
1641
+ self.Color = Color
1642
+ self.BackgroundColor = BackgroundColor
1643
+ self.Family = Family
1644
+ self.Style = Style
1645
+ self.Weight = Weight
1646
+ self.Underlined = Underlined
1647
+ if not Font:
1648
+ self.FaceName = ''
1649
+ else:
1650
+ self.FaceName = Font.GetFaceName()
1651
+ self.Family = Font.GetFamily()
1652
+ self.Style = Font.GetStyle()
1653
+ self.Underlined = Font.GetUnderlined()
1654
+ self.Weight = Font.GetWeight()
1655
+
1656
+ # Experimental max font size value on wxGTK2: this works OK on
1657
+ # my system. If it's a lot larger, there is a crash, with the
1658
+ # message:
1659
+ #
1660
+ # The application 'FloatCanvasDemo.py' lost its
1661
+ # connection to the display :0.0; most likely the X server was
1662
+ # shut down or you killed/destroyed the application.
1663
+ #
1664
+ # Windows and OS-X seem to be better behaved in this regard.
1665
+ # They may not draw it, but they don't crash either!
1666
+ self.MaxFontSize = 1000
1667
+ self.MinFontSize = 1 # this can be changed to set a minimum size
1668
+ self.DisappearWhenSmall = True
1669
+ self.ShiftFun = self.ShiftFunDict[Position]
1670
+
1671
+ self.CalcBoundingBox()
1672
+
1673
+ def LayoutText(self):
1674
+ # This will be called when the text is re-set
1675
+ # nothing much to be done here
1676
+ self.CalcBoundingBox()
1677
+
1678
+ def CalcBoundingBox(self):
1679
+ ## this isn't exact, as fonts don't scale exactly.
1680
+ dc = wx.MemoryDC()
1681
+ bitmap = wx.Bitmap(1, 1)
1682
+ dc.SelectObject(bitmap) #wxMac needs a Bitmap selected for GetTextExtent to work.
1683
+ DrawingSize = 40 # pts This effectively determines the resolution that the BB is computed to.
1684
+ ScaleFactor = float(self.Size) / DrawingSize
1685
+ self.SetFont(DrawingSize, self.Family, self.Style, self.Weight, self.Underlined, self.FaceName)
1686
+ dc.SetFont(self.Font)
1687
+ (w,h) = dc.GetTextExtent(self.String)
1688
+ w = w * ScaleFactor
1689
+ h = h * ScaleFactor
1690
+ x, y = self.ShiftFun(self.XY[0], self.XY[1], w, h, world = 1)
1691
+ self.BoundingBox = BBox.asBBox(((x, y-h ),(x + w, y)))
1692
+
1693
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
1694
+ (X,Y) = WorldToPixel( (self.XY) )
1695
+
1696
+ # compute the font size:
1697
+ Size = abs( ScaleWorldToPixel( (self.Size, self.Size) )[1] ) # only need a y coordinate length
1698
+ ## Check to see if the font size is large enough to blow up the X font server
1699
+ ## If so, limit it. Would it be better just to not draw it?
1700
+ ## note that this limit is dependent on how much memory you have, etc.
1701
+ Size = min(Size, self.MaxFontSize)
1702
+ Size = max(Size, self.MinFontSize) # smallest size you want - default to 0
1703
+
1704
+ # Draw the Text
1705
+ if not( self.DisappearWhenSmall and Size <= self.MinFontSize) : # don't try to draw a zero sized font!
1706
+ self.SetFont(Size, self.Family, self.Style, self.Weight, self.Underlined, self.FaceName)
1707
+ dc.SetFont(self.Font)
1708
+ dc.SetTextForeground(self.Color)
1709
+ if self.BackgroundColor:
1710
+ dc.SetBackgroundMode(wx.SOLID)
1711
+ dc.SetTextBackground(self.BackgroundColor)
1712
+ else:
1713
+ dc.SetBackgroundMode(wx.TRANSPARENT)
1714
+ (w,h) = dc.GetTextExtent(self.String)
1715
+ # compute the shift, and adjust the coordinates, if neccesary
1716
+ # This had to be put in here, because it changes with Zoom, as
1717
+ # fonts don't scale exactly.
1718
+ xy = self.ShiftFun(X, Y, w, h)
1719
+ dc.DrawText(self.String, xy)
1720
+
1721
+ if HTdc and self.HitAble:
1722
+ HTdc.SetPen(self.HitPen)
1723
+ HTdc.SetBrush(self.HitBrush)
1724
+ HTdc.DrawRectangle(xy, (w, h))
1725
+
1726
+ class ScaledTextBox(TextObjectMixin, DrawObject):
1727
+ """
1728
+ Draws a text object
1729
+
1730
+ The object is scaled when zoomed.
1731
+
1732
+ The hit-test is done on the entire text extent
1733
+
1734
+ Bugs/Limitations:
1735
+
1736
+ As fonts are scaled, they do end up a little different, so you don't
1737
+ get exactly the same picture as you scale up and down, but it's
1738
+ pretty darn close.
1739
+
1740
+ On wxGTK1 on my Linux system, at least, using a font of over about
1741
+ 1000 pts. brings the system to a halt. It's the Font Server using
1742
+ huge amounts of memory. My work around is to max the font size to
1743
+ 1000 points, so it won't scale past there. GTK2 uses smarter font
1744
+ drawing, so that may not be an issue in future versions, so feel
1745
+ free to test. Another smarter way to do it would be to set a global
1746
+ zoom limit at that point.
1747
+
1748
+ """
1749
+
1750
+ def __init__(self, String,
1751
+ Point,
1752
+ Size,
1753
+ Color = "Black",
1754
+ BackgroundColor = None,
1755
+ LineColor = 'Black',
1756
+ LineStyle = 'Solid',
1757
+ LineWidth = 1,
1758
+ Width = None,
1759
+ PadSize = None,
1760
+ Family = wx.FONTFAMILY_MODERN,
1761
+ Style = wx.FONTSTYLE_NORMAL,
1762
+ Weight = wx.FONTWEIGHT_NORMAL,
1763
+ Underlined = False,
1764
+ Position = 'tl',
1765
+ Alignment = "left",
1766
+ Font = None,
1767
+ LineSpacing = 1.0,
1768
+ InForeground = False):
1769
+ """
1770
+ Default class constructor.
1771
+
1772
+ :param `Point`: takes a 2-tuple, or a (2,) `NumPy <http://www.numpy.org/>`_
1773
+ array of point coordinates
1774
+ :param integer `Size`: size in World units
1775
+ :param `Color`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
1776
+ :param `BackgroundColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
1777
+ :param `LineColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
1778
+ :param `LineWidth`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineWidth`
1779
+ :param `Width`: width in pixels or ``None``, text will be wrapped to
1780
+ the given width.
1781
+ :param `PadSize`: padding in world units or ``None``, if specified it
1782
+ will creating a space (margin) around the text
1783
+ :param wx.FontFamily `Family`: a valid :ref:`wx.FontFamily`
1784
+ :param wx.FontStyle `Style`: a valid :ref:`wx.FontStyle`
1785
+ :param wx.FontWeight `Weight`: a valid :ref:`wx.FontWeight`
1786
+ :param boolean `Underlined`: underline the text
1787
+ :param string `Position`: a two character string indicating where in
1788
+ relation to the coordinates the box should be oriented
1789
+
1790
+ ============== ==========================
1791
+ 1st character Meaning
1792
+ ============== ==========================
1793
+ ``t`` top
1794
+ ``c`` center
1795
+ ``b`` bottom
1796
+ ============== ==========================
1797
+
1798
+ ============== ==========================
1799
+ 2nd character Meaning
1800
+ ============== ==========================
1801
+ ``l`` left
1802
+ ``c`` center
1803
+ ``r`` right
1804
+ ============== ==========================
1805
+
1806
+ :param `Alignment`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineWidth`
1807
+ :param wx.Font `Font`: alternatively a valid :class:`wx.Font` can be defined
1808
+ in which case the above will be ignored
1809
+ :param float `LineSpacing`: the line space to be used
1810
+ :param boolean `InForeground`: should object be in foreground
1811
+
1812
+ """
1813
+ DrawObject.__init__(self,InForeground)
1814
+
1815
+ self.XY = N.array(Point, float)
1816
+ self.Size = Size
1817
+ self.Color = Color
1818
+ self.BackgroundColor = BackgroundColor
1819
+ self.LineColor = LineColor
1820
+ self.LineStyle = LineStyle
1821
+ self.LineWidth = LineWidth
1822
+ self.Width = Width
1823
+ if PadSize is None: # the default is just a little bit of padding
1824
+ self.PadSize = Size/10.0
1825
+ else:
1826
+ self.PadSize = float(PadSize)
1827
+ self.Family = Family
1828
+ self.Style = Style
1829
+ self.Weight = Weight
1830
+ self.Underlined = Underlined
1831
+ self.Alignment = Alignment.lower()
1832
+ self.LineSpacing = float(LineSpacing)
1833
+ self.Position = Position
1834
+
1835
+ if not Font:
1836
+ self.FaceName = ''
1837
+ else:
1838
+ self.FaceName = Font.GetFaceName()
1839
+ self.Family = Font.GetFamily()
1840
+ self.Style = Font.GetStyle()
1841
+ self.Underlined = Font.GetUnderlined()
1842
+ self.Weight = Font.GetWeight()
1843
+
1844
+ # Experimental max font size value on wxGTK2: this works OK on
1845
+ # my system. If it's a lot larger, there is a crash, with the
1846
+ # message:
1847
+ #
1848
+ # The application 'FloatCanvasDemo.py' lost its
1849
+ # connection to the display :0.0; most likely the X server was
1850
+ # shut down or you killed/destroyed the application.
1851
+ #
1852
+ # Windows and OS-X seem to be better behaved in this regard.
1853
+ # They may not draw it, but they don't crash either!
1854
+
1855
+ self.MaxFontSize = 1000
1856
+ self.MinFontSize = 1 # this can be changed to set a larger minimum size
1857
+ self.DisappearWhenSmall = True
1858
+
1859
+ self.ShiftFun = self.ShiftFunDict[Position]
1860
+
1861
+ self.String = String
1862
+ self.LayoutText()
1863
+ self.CalcBoundingBox()
1864
+
1865
+ self.SetPen(LineColor,LineStyle,LineWidth)
1866
+ self.SetBrush(BackgroundColor, "Solid")
1867
+
1868
+
1869
+ def WrapToWidth(self):
1870
+ dc = wx.MemoryDC()
1871
+ bitmap = wx.Bitmap(1, 1)
1872
+ dc.SelectObject(bitmap) #wxMac needs a Bitmap selected for GetTextExtent to work.
1873
+ DrawingSize = self.LayoutFontSize # pts This effectively determines the resolution that the BB is computed to.
1874
+ ScaleFactor = float(self.Size) / DrawingSize
1875
+ Width = (self.Width - 2*self.PadSize) / ScaleFactor #Width to wrap to
1876
+ self.SetFont(DrawingSize, self.Family, self.Style, self.Weight, self.Underlined, self.FaceName)
1877
+ dc.SetFont(self.Font)
1878
+ NewStrings = []
1879
+ for s in self.Strings:
1880
+ #beginning = True
1881
+ text = s.split(" ")
1882
+ text.reverse()
1883
+ LineLength = 0
1884
+ NewText = text[-1]
1885
+ del text[-1]
1886
+ while text:
1887
+ w = dc.GetTextExtent(' ' + text[-1])[0]
1888
+ if LineLength + w <= Width:
1889
+ NewText += ' '
1890
+ NewText += text[-1]
1891
+ LineLength = dc.GetTextExtent(NewText)[0]
1892
+ else:
1893
+ NewStrings.append(NewText)
1894
+ NewText = text[-1]
1895
+ LineLength = dc.GetTextExtent(text[-1])[0]
1896
+ del text[-1]
1897
+ NewStrings.append(NewText)
1898
+ self.Strings = NewStrings
1899
+
1900
+ def ReWrap(self, Width):
1901
+ self.Width = Width
1902
+ self.LayoutText()
1903
+
1904
+ def LayoutText(self):
1905
+ """
1906
+ Calculates the positions of the words of text.
1907
+
1908
+ This isn't exact, as fonts don't scale exactly.
1909
+ To help this, the position of each individual word
1910
+ is stored separately, so that the general layout stays
1911
+ the same in world coordinates, as the fonts scale.
1912
+
1913
+ """
1914
+ self.Strings = self.String.split("\n")
1915
+ if self.Width:
1916
+ self.WrapToWidth()
1917
+
1918
+ dc = wx.MemoryDC()
1919
+ bitmap = wx.Bitmap(1, 1)
1920
+ dc.SelectObject(bitmap) #wxMac needs a Bitmap selected for GetTextExtent to work.
1921
+
1922
+ DrawingSize = self.LayoutFontSize # pts This effectively determines the resolution that the BB is computed to.
1923
+ ScaleFactor = float(self.Size) / DrawingSize
1924
+
1925
+ self.SetFont(DrawingSize, self.Family, self.Style, self.Weight, self.Underlined, self.FaceName)
1926
+ dc.SetFont(self.Font)
1927
+ TextHeight = dc.GetTextExtent("X")[1]
1928
+ SpaceWidth = dc.GetTextExtent(" ")[0]
1929
+ LineHeight = TextHeight * self.LineSpacing
1930
+
1931
+ LineWidths = N.zeros((len(self.Strings),), float)
1932
+ y = 0
1933
+ Words = []
1934
+ AllLinePoints = []
1935
+
1936
+ for i, s in enumerate(self.Strings):
1937
+ LineWidths[i] = 0
1938
+ LineWords = s.split(" ")
1939
+ LinePoints = N.zeros((len(LineWords),2), float)
1940
+ for j, word in enumerate(LineWords):
1941
+ if j > 0:
1942
+ LineWidths[i] += SpaceWidth
1943
+ Words.append(word)
1944
+ LinePoints[j] = (LineWidths[i], y)
1945
+ w = dc.GetTextExtent(word)[0]
1946
+ LineWidths[i] += w
1947
+ y -= LineHeight
1948
+ AllLinePoints.append(LinePoints)
1949
+ TextWidth = N.maximum.reduce(LineWidths)
1950
+ self.Words = Words
1951
+
1952
+ if self.Width is None:
1953
+ BoxWidth = TextWidth * ScaleFactor + 2*self.PadSize
1954
+ else: # use the defined Width
1955
+ BoxWidth = self.Width
1956
+ Points = N.zeros((0,2), float)
1957
+
1958
+ for i, LinePoints in enumerate(AllLinePoints):
1959
+ ## Scale to World Coords.
1960
+ LinePoints *= (ScaleFactor, ScaleFactor)
1961
+ if self.Alignment == 'left':
1962
+ LinePoints[:,0] += self.PadSize
1963
+ elif self.Alignment == 'center':
1964
+ LinePoints[:,0] += (BoxWidth - LineWidths[i]*ScaleFactor)/2.0
1965
+ elif self.Alignment == 'right':
1966
+ LinePoints[:,0] += (BoxWidth - LineWidths[i]*ScaleFactor-self.PadSize)
1967
+ Points = N.concatenate((Points, LinePoints))
1968
+
1969
+ BoxHeight = -(Points[-1,1] - (TextHeight * ScaleFactor)) + 2*self.PadSize
1970
+ #(x,y) = self.ShiftFun(self.XY[0], self.XY[1], BoxWidth, BoxHeight, world=1)
1971
+ Points += (0, -self.PadSize)
1972
+ self.Points = Points
1973
+ self.BoxWidth = BoxWidth
1974
+ self.BoxHeight = BoxHeight
1975
+ self.CalcBoundingBox()
1976
+
1977
+ def CalcBoundingBox(self):
1978
+ """Calculates the Bounding Box"""
1979
+ w, h = self.BoxWidth, self.BoxHeight
1980
+ x, y = self.ShiftFun(self.XY[0], self.XY[1], w, h, world=1)
1981
+ self.BoundingBox = BBox.asBBox(((x, y-h ),(x + w, y)))
1982
+
1983
+ def GetBoxRect(self):
1984
+ wh = (self.BoxWidth, self.BoxHeight)
1985
+ xy = (self.BoundingBox[0,0], self.BoundingBox[1,1])
1986
+
1987
+ return (xy, wh)
1988
+
1989
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
1990
+ xy, wh = self.GetBoxRect()
1991
+
1992
+ Points = self.Points + xy
1993
+ Points = WorldToPixel(Points)
1994
+ xy = WorldToPixel(xy)
1995
+ wh = ScaleWorldToPixel(wh) * (1,-1)
1996
+
1997
+ # compute the font size:
1998
+ Size = abs( ScaleWorldToPixel( (self.Size, self.Size) )[1] ) # only need a y coordinate length
1999
+ ## Check to see if the font size is large enough to blow up the X font server
2000
+ ## If so, limit it. Would it be better just to not draw it?
2001
+ ## note that this limit is dependent on how much memory you have, etc.
2002
+ Size = min(Size, self.MaxFontSize)
2003
+
2004
+ Size = max(Size, self.MinFontSize) # smallest size you want - default to 1
2005
+
2006
+ # Draw The Box
2007
+ if (self.LineStyle and self.LineColor) or self.BackgroundColor:
2008
+ dc.SetBrush(self.Brush)
2009
+ dc.SetPen(self.Pen)
2010
+ dc.DrawRectangle(xy , wh)
2011
+
2012
+ # Draw the Text
2013
+ if not( self.DisappearWhenSmall and Size <= self.MinFontSize) : # don't try to draw a zero sized font!
2014
+ self.SetFont(Size, self.Family, self.Style, self.Weight, self.Underlined, self.FaceName)
2015
+ dc.SetFont(self.Font)
2016
+ dc.SetTextForeground(self.Color)
2017
+ dc.SetBackgroundMode(wx.TRANSPARENT)
2018
+ dc.DrawTextList(self.Words, Points)
2019
+
2020
+ # Draw the hit box.
2021
+ if HTdc and self.HitAble:
2022
+ HTdc.SetPen(self.HitPen)
2023
+ HTdc.SetBrush(self.HitBrush)
2024
+ HTdc.DrawRectangle(xy, wh)
2025
+
2026
+ class Bitmap(TextObjectMixin, DrawObject):
2027
+ """
2028
+ Draws a bitmap
2029
+
2030
+ The size is fixed, and does not scale with the drawing.
2031
+
2032
+ """
2033
+
2034
+ def __init__(self, Bitmap, XY,
2035
+ Position='tl',
2036
+ InForeground=False):
2037
+ """
2038
+ Default class constructor.
2039
+
2040
+ :param wx.Bitmap `Bitmap`: the bitmap to be drawn
2041
+ :param `XY`: the (x, y) coordinate of the corner of the bitmap, or a 2-tuple,
2042
+ or a (2,) `NumPy <http://www.numpy.org/>`_ array
2043
+ :param string `Position`: a two character string indicating where in relation to the coordinates
2044
+ the bitmap should be oriented
2045
+
2046
+ ============== ==========================
2047
+ 1st character Meaning
2048
+ ============== ==========================
2049
+ ``t`` top
2050
+ ``c`` center
2051
+ ``b`` bottom
2052
+ ============== ==========================
2053
+
2054
+ ============== ==========================
2055
+ 2nd character Meaning
2056
+ ============== ==========================
2057
+ ``l`` left
2058
+ ``c`` center
2059
+ ``r`` right
2060
+ ============== ==========================
2061
+
2062
+ :param boolean `InForeground`: should object be in foreground
2063
+
2064
+ """
2065
+
2066
+ DrawObject.__init__(self,InForeground)
2067
+
2068
+ if type(Bitmap) == wx.Bitmap:
2069
+ self.Bitmap = Bitmap
2070
+ elif type(Bitmap) == wx.Image:
2071
+ self.Bitmap = wx.Bitmap(Bitmap)
2072
+
2073
+ # Note the BB is just the point, as the size in World coordinates is not fixed
2074
+ self.BoundingBox = BBox.asBBox( (XY,XY) )
2075
+
2076
+ self.XY = XY
2077
+
2078
+ (self.Width, self.Height) = self.Bitmap.GetWidth(), self.Bitmap.GetHeight()
2079
+ self.ShiftFun = self.ShiftFunDict[Position]
2080
+
2081
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
2082
+ XY = WorldToPixel(self.XY)
2083
+ XY = self.ShiftFun(XY[0], XY[1], self.Width, self.Height)
2084
+ dc.DrawBitmap(self.Bitmap, XY, True)
2085
+ if HTdc and self.HitAble:
2086
+ HTdc.SetPen(self.HitPen)
2087
+ HTdc.SetBrush(self.HitBrush)
2088
+ HTdc.DrawRectangle(XY, (self.Width, self.Height) )
2089
+
2090
+ class ScaledBitmap(TextObjectMixin, DrawObject):
2091
+ """
2092
+ Draws a scaled bitmap
2093
+
2094
+ The size scales with the drawing
2095
+
2096
+ """
2097
+
2098
+ def __init__(self,
2099
+ Bitmap,
2100
+ XY,
2101
+ Height,
2102
+ Position = 'tl',
2103
+ InForeground = False):
2104
+ """
2105
+ Default class constructor.
2106
+
2107
+ :param wx.Bitmap `Bitmap`: the bitmap to be drawn
2108
+ :param `XY`: the (x, y) coordinate of the corner of the scaled bitmap,
2109
+ or a 2-tuple, or a (2,) `NumPy <http://www.numpy.org/>`_ array
2110
+ :param `Height`: height to be used, width is calculated from the aspect ratio of the bitmap
2111
+ :param string `Position`: a two character string indicating where in relation to the coordinates
2112
+ the bitmap should be oriented
2113
+
2114
+ ============== ==========================
2115
+ 1st character Meaning
2116
+ ============== ==========================
2117
+ ``t`` top
2118
+ ``c`` center
2119
+ ``b`` bottom
2120
+ ============== ==========================
2121
+
2122
+ ============== ==========================
2123
+ 2nd character Meaning
2124
+ ============== ==========================
2125
+ ``l`` left
2126
+ ``c`` center
2127
+ ``r`` right
2128
+ ============== ==========================
2129
+
2130
+ :param boolean `InForeground`: should object be in foreground
2131
+
2132
+ """
2133
+
2134
+ DrawObject.__init__(self,InForeground)
2135
+
2136
+ if type(Bitmap) == wx.Bitmap:
2137
+ self.Image = Bitmap.ConvertToImage()
2138
+ elif type(Bitmap) == wx.Image:
2139
+ self.Image = Bitmap
2140
+ else:
2141
+ raise ValueError("'Bitmap' must be a wx.Bitmap or wx.Image object not %s" % type(Bitmap))
2142
+
2143
+ self.XY = XY
2144
+ self.Height = Height
2145
+ (self.bmpWidth, self.bmpHeight) = float(self.Image.GetWidth()), float(self.Image.GetHeight())
2146
+ self.Width = self.bmpWidth / self.bmpHeight * Height
2147
+ self.ShiftFun = self.ShiftFunDict[Position]
2148
+ self.CalcBoundingBox()
2149
+ self.ScaledBitmap = None
2150
+ self.ScaledHeight = None
2151
+
2152
+ def CalcBoundingBox(self):
2153
+ """Calculate the bounding box."""
2154
+ ## this isn't exact, as fonts don't scale exactly.
2155
+ w, h = self.Width, self.Height
2156
+ x, y = self.ShiftFun(self.XY[0], self.XY[1], w, h, world = 1)
2157
+ self.BoundingBox = BBox.asBBox( ( (x, y-h ), (x + w, y) ) )
2158
+
2159
+
2160
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
2161
+ XY = WorldToPixel(self.XY)
2162
+ H = ScaleWorldToPixel(self.Height)[0]
2163
+ W = H * (self.bmpWidth / self.bmpHeight)
2164
+ H = int(H)
2165
+ W = int(W)
2166
+ if (self.ScaledBitmap is None) or (H != self.ScaledHeight) :
2167
+ self.ScaledHeight = H
2168
+ Img = self.Image.Scale(W, H)
2169
+ self.ScaledBitmap = wx.Bitmap(Img)
2170
+
2171
+ XY = self.ShiftFun(XY[0], XY[1], W, H)
2172
+ dc.DrawBitmap(self.ScaledBitmap, XY, True)
2173
+ if HTdc and self.HitAble:
2174
+ HTdc.SetPen(self.HitPen)
2175
+ HTdc.SetBrush(self.HitBrush)
2176
+ HTdc.DrawRectangle(XY, (W, H) )
2177
+
2178
+ class ScaledBitmap2(TextObjectMixin, DrawObject, ):
2179
+ """
2180
+ Draws a scaled bitmap
2181
+
2182
+ An alternative scaled bitmap that only scaled the required amount of
2183
+ the main bitmap when zoomed in: EXPERIMENTAL!
2184
+
2185
+ """
2186
+
2187
+ def __init__(self,
2188
+ Bitmap,
2189
+ XY,
2190
+ Height,
2191
+ Width=None,
2192
+ Position = 'tl',
2193
+ InForeground = False):
2194
+ """
2195
+ Default class constructor.
2196
+
2197
+ :param wx.Bitmap `Bitmap`: the bitmap to be drawn
2198
+ :param `XY`: the (x, y) coordinate of the corner of the scaled bitmap,
2199
+ or a 2-tuple, or a (2,) `NumPy <http://www.numpy.org/>`_ array
2200
+ :param `Height`: height to be used
2201
+ :param `Width`: width to be used, if ``None`` width is calculated from the aspect ratio of the bitmap
2202
+ :param string `Position`: a two character string indicating where in relation to the coordinates
2203
+ the bitmap should be oriented
2204
+
2205
+ ============== ==========================
2206
+ 1st character Meaning
2207
+ ============== ==========================
2208
+ ``t`` top
2209
+ ``c`` center
2210
+ ``b`` bottom
2211
+ ============== ==========================
2212
+
2213
+ ============== ==========================
2214
+ 2nd character Meaning
2215
+ ============== ==========================
2216
+ ``l`` left
2217
+ ``c`` center
2218
+ ``r`` right
2219
+ ============== ==========================
2220
+
2221
+ :param boolean `InForeground`: should object be in foreground
2222
+
2223
+ """
2224
+
2225
+ DrawObject.__init__(self,InForeground)
2226
+
2227
+ if type(Bitmap) == wx.Bitmap:
2228
+ self.Image = Bitmap.ConvertToImage()
2229
+ elif type(Bitmap) == wx.Image:
2230
+ self.Image = Bitmap
2231
+
2232
+ self.XY = N.array(XY, float)
2233
+ self.Height = Height
2234
+ (self.bmpWidth, self.bmpHeight) = float(self.Image.GetWidth()), float(self.Image.GetHeight())
2235
+ self.bmpWH = N.array((self.bmpWidth, self.bmpHeight), N.int32)
2236
+ ## fixme: this should all accommodate different scales for X and Y
2237
+ if Width is None:
2238
+ self.BmpScale = float(self.bmpHeight) / Height
2239
+ self.Width = self.bmpWidth / self.BmpScale
2240
+ self.WH = N.array((self.Width, Height), float)
2241
+ ##fixme: should this have a y = -1 to shift to y-up?
2242
+ self.BmpScale = self.bmpWH / self.WH
2243
+
2244
+ #print("bmpWH:", self.bmpWH)
2245
+ #print("Width, Height:", self.WH)
2246
+ #print("self.BmpScale", self.BmpScale)
2247
+ self.ShiftFun = self.ShiftFunDict[Position]
2248
+ self.CalcBoundingBox()
2249
+ self.ScaledBitmap = None # cache of the last existing scaled bitmap
2250
+
2251
+ def CalcBoundingBox(self):
2252
+ """Calculate the bounding box."""
2253
+ ## this isn't exact, as fonts don't scale exactly.
2254
+ w,h = self.Width, self.Height
2255
+ x, y = self.ShiftFun(self.XY[0], self.XY[1], w, h, world = 1)
2256
+ self.BoundingBox = BBox.asBBox( ((x, y-h ), (x + w, y)) )
2257
+
2258
+ def WorldToBitmap(self, Pw):
2259
+ """Computes the bitmap coords from World coords."""
2260
+ delta = Pw - self.XY
2261
+ Pb = delta * self.BmpScale
2262
+ Pb *= (1, -1) ##fixme: this may only works for Yup projection!
2263
+ ## and may only work for top left position
2264
+
2265
+ return Pb.astype(N.int_)
2266
+
2267
+ def _DrawEntireBitmap(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc):
2268
+ """
2269
+ this is pretty much the old code
2270
+
2271
+ Scales and Draws the entire bitmap.
2272
+
2273
+ """
2274
+ XY = WorldToPixel(self.XY)
2275
+ H = ScaleWorldToPixel(self.Height)[0]
2276
+ W = H * (self.bmpWidth / self.bmpHeight)
2277
+ if (self.ScaledBitmap is None) or (self.ScaledBitmap[0] != (0, 0, self.bmpWidth, self.bmpHeight, W, H) ):
2278
+ #if True: #fixme: (self.ScaledBitmap is None) or (H != self.ScaledHeight) :
2279
+ self.ScaledHeight = H
2280
+ #print("Scaling to:", W, H)
2281
+ Img = self.Image.Scale(W, H)
2282
+ bmp = wx.Bitmap(Img)
2283
+ self.ScaledBitmap = ((0, 0, self.bmpWidth, self.bmpHeight , W, H), bmp)# this defines the cached bitmap
2284
+ else:
2285
+ #print("Using Cached bitmap")
2286
+ bmp = self.ScaledBitmap[1]
2287
+ XY = self.ShiftFun(XY[0], XY[1], W, H)
2288
+ dc.DrawBitmap(bmp, XY, True)
2289
+ if HTdc and self.HitAble:
2290
+ HTdc.SetPen(self.HitPen)
2291
+ HTdc.SetBrush(self.HitBrush)
2292
+ HTdc.DrawRectangle(XY, (W, H) )
2293
+
2294
+ def _DrawSubBitmap(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc):
2295
+ """
2296
+ Subsets just the part of the bitmap that is visible
2297
+ then scales and draws that.
2298
+
2299
+ """
2300
+ BBworld = BBox.asBBox(self._Canvas.ViewPortBB)
2301
+ BBbitmap = BBox.fromPoints(self.WorldToBitmap(BBworld))
2302
+
2303
+ XYs = WorldToPixel(self.XY)
2304
+ # figure out subimage:
2305
+ # fixme: this should be able to be done more succinctly!
2306
+
2307
+ if BBbitmap[0,0] < 0:
2308
+ Xb = 0
2309
+ elif BBbitmap[0,0] > self.bmpWH[0]: # off the bitmap
2310
+ Xb = 0
2311
+ else:
2312
+ Xb = BBbitmap[0,0]
2313
+ XYs[0] = 0 # draw at origin
2314
+
2315
+ if BBbitmap[0,1] < 0:
2316
+ Yb = 0
2317
+ elif BBbitmap[0,1] > self.bmpWH[1]: # off the bitmap
2318
+ Yb = 0
2319
+ ShouldDraw = False
2320
+ else:
2321
+ Yb = BBbitmap[0,1]
2322
+ XYs[1] = 0 # draw at origin
2323
+
2324
+ if BBbitmap[1,0] < 0:
2325
+ #off the screen -- This should never happen!
2326
+ Wb = 0
2327
+ elif BBbitmap[1,0] > self.bmpWH[0]:
2328
+ Wb = self.bmpWH[0] - Xb
2329
+ else:
2330
+ Wb = BBbitmap[1,0] - Xb
2331
+
2332
+ if BBbitmap[1,1] < 0:
2333
+ # off the screen -- This should never happen!
2334
+ Hb = 0
2335
+ ShouldDraw = False
2336
+ elif BBbitmap[1,1] > self.bmpWH[1]:
2337
+ Hb = self.bmpWH[1] - Yb
2338
+ else:
2339
+ Hb = BBbitmap[1,1] - Yb
2340
+
2341
+ FullHeight = ScaleWorldToPixel(self.Height)[0]
2342
+ scale = float(FullHeight) / float(self.bmpWH[1])
2343
+ Ws = int(scale * Wb + 0.5) # add the 0.5 to round
2344
+ Hs = int(scale * Hb + 0.5)
2345
+ if (self.ScaledBitmap is None) or (self.ScaledBitmap[0] != (Xb, Yb, Wb, Hb, Ws, Ws) ):
2346
+ Img = self.Image.GetSubImage(wx.Rect(Xb, Yb, Wb, Hb))
2347
+ #print("rescaling with High quality")
2348
+ Img.Rescale(Ws, Hs, quality=wx.IMAGE_QUALITY_HIGH)
2349
+ bmp = wx.Bitmap(Img)
2350
+ self.ScaledBitmap = ((Xb, Yb, Wb, Hb, Ws, Ws), bmp)# this defines the cached bitmap
2351
+ #XY = self.ShiftFun(XY[0], XY[1], W, H)
2352
+ #fixme: get the shiftfun working!
2353
+ else:
2354
+ #print("Using cached bitmap")
2355
+ ##fixme: The cached bitmap could be used if the one needed is the same scale, but
2356
+ ## a subset of the cached one.
2357
+ bmp = self.ScaledBitmap[1]
2358
+ dc.DrawBitmap(bmp, XYs, True)
2359
+
2360
+ if HTdc and self.HitAble:
2361
+ HTdc.SetPen(self.HitPen)
2362
+ HTdc.SetBrush(self.HitBrush)
2363
+ HTdc.DrawRectangle(XYs, (Ws, Hs) )
2364
+
2365
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
2366
+ BBworld = BBox.asBBox(self._Canvas.ViewPortBB)
2367
+ ## first see if entire bitmap is displayed:
2368
+ if BBworld.Inside(self.BoundingBox):
2369
+ #print("Drawing entire bitmap with old code")
2370
+ self._DrawEntireBitmap(dc , WorldToPixel, ScaleWorldToPixel, HTdc)
2371
+ return None
2372
+ elif BBworld.Overlaps(self.BoundingBox):
2373
+ #BBbitmap = BBox.fromPoints(self.WorldToBitmap(BBworld))
2374
+ #print("Drawing a sub-bitmap")
2375
+ self._DrawSubBitmap(dc , WorldToPixel, ScaleWorldToPixel, HTdc)
2376
+ else:
2377
+ #print("Not Drawing -- no part of image is showing")
2378
+ pass
2379
+
2380
+ class DotGrid:
2381
+ """
2382
+ An example of a Grid Object -- it is set on the FloatCanvas with one of::
2383
+
2384
+ FloatCanvas.GridUnder = Grid
2385
+ FloatCanvas.GridOver = Grid
2386
+
2387
+ It will be drawn every time, regardless of the viewport.
2388
+
2389
+ In its _Draw method, it computes what to draw, given the ViewPortBB
2390
+ of the Canvas it's being drawn on.
2391
+
2392
+ """
2393
+ def __init__(self, Spacing, Size = 2, Color = "Black", Cross=False, CrossThickness = 1):
2394
+
2395
+ self.Spacing = N.array(Spacing, float)
2396
+ self.Spacing.shape = (2,)
2397
+ self.Size = Size
2398
+ self.Color = Color
2399
+ self.Cross = Cross
2400
+ self.CrossThickness = CrossThickness
2401
+
2402
+ def CalcPoints(self, Canvas):
2403
+ ViewPortBB = Canvas.ViewPortBB
2404
+
2405
+ Spacing = self.Spacing
2406
+
2407
+ minx, miny = N.floor(ViewPortBB[0] / Spacing) * Spacing
2408
+ maxx, maxy = N.ceil(ViewPortBB[1] / Spacing) * Spacing
2409
+
2410
+ ##fixme: this could use vstack or something with numpy
2411
+ x = N.arange(minx, maxx+Spacing[0], Spacing[0]) # making sure to get the last point
2412
+ y = N.arange(miny, maxy+Spacing[1], Spacing[1]) # an extra is OK
2413
+ Points = N.zeros((len(y), len(x), 2), float)
2414
+ x.shape = (1,-1)
2415
+ y.shape = (-1,1)
2416
+ Points[:,:,0] += x
2417
+ Points[:,:,1] += y
2418
+ Points.shape = (-1,2)
2419
+
2420
+ return Points
2421
+
2422
+ def _Draw(self, dc, Canvas):
2423
+ Points = self.CalcPoints(Canvas)
2424
+
2425
+ Points = Canvas.WorldToPixel(Points)
2426
+
2427
+ dc.SetPen(wx.Pen(self.Color,self.CrossThickness))
2428
+
2429
+ if self.Cross: # Use cross shaped markers
2430
+ #Horizontal lines
2431
+ LinePoints = N.concatenate((Points + (self.Size,0),Points + (-self.Size,0)),1)
2432
+ dc.DrawLineList(LinePoints)
2433
+ # Vertical Lines
2434
+ LinePoints = N.concatenate((Points + (0,self.Size),Points + (0,-self.Size)),1)
2435
+ dc.DrawLineList(LinePoints)
2436
+ pass
2437
+ else: # use dots
2438
+ ## Note: this code borrowed from Pointset -- it really shouldn't be repeated here!.
2439
+ if self.Size <= 1:
2440
+ dc.DrawPointList(Points)
2441
+ elif self.Size <= 2:
2442
+ dc.DrawPointList(Points + (0,-1))
2443
+ dc.DrawPointList(Points + (0, 1))
2444
+ dc.DrawPointList(Points + (1, 0))
2445
+ dc.DrawPointList(Points + (-1,0))
2446
+ else:
2447
+ dc.SetBrush(wx.Brush(self.Color))
2448
+ radius = int(round(self.Size/2))
2449
+ ##fixme: I really should add a DrawCircleList to wxPython
2450
+ if len(Points) > 100:
2451
+ xy = Points
2452
+ xywh = N.concatenate((xy-radius, N.ones(xy.shape) * self.Size ), 1 )
2453
+ dc.DrawEllipseList(xywh)
2454
+ else:
2455
+ for xy in Points:
2456
+ dc.DrawCircle(xy[0],xy[1], radius)
2457
+
2458
+ class Arc(XYObjectMixin, LineAndFillMixin, DrawObject):
2459
+ """
2460
+ Draws an arc of a circle, centered on point ``CenterXY``, from
2461
+ the first point ``StartXY`` to the second ``EndXY``.
2462
+
2463
+ The arc is drawn in an anticlockwise direction from the start point to
2464
+ the end point.
2465
+
2466
+ """
2467
+ def __init__(self,
2468
+ StartXY,
2469
+ EndXY,
2470
+ CenterXY,
2471
+ LineColor = "Black",
2472
+ LineStyle = "Solid",
2473
+ LineWidth = 1,
2474
+ FillColor = None,
2475
+ FillStyle = "Solid",
2476
+ InForeground = False):
2477
+ """
2478
+ Default class constructor.
2479
+
2480
+ :param `StartXY`: start point, takes a 2-tuple, or a (2,)
2481
+ `NumPy <http://www.numpy.org/>`_ array of point coordinates
2482
+ :param `EndXY`: end point, takes a 2-tuple, or a (2,)
2483
+ `NumPy <http://www.numpy.org/>`_ array of point coordinates
2484
+ :param `CenterXY`: center point, takes a 2-tuple, or a (2,)
2485
+ `NumPy <http://www.numpy.org/>`_ array of point coordinates
2486
+ :param `LineColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
2487
+ :param `LineStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineStyle`
2488
+ :param `LineWidth`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineWidth`
2489
+ :param `FillColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
2490
+ :param `FillStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetFillStyle`
2491
+ :param boolean `InForeground`: should object be in foreground
2492
+
2493
+ """
2494
+
2495
+ DrawObject.__init__(self, InForeground)
2496
+
2497
+ # There is probably a more elegant way to do this next section
2498
+ # The bounding box just gets set to the WH of a circle, with center at CenterXY
2499
+ # This is suitable for a pie chart as it will be a circle anyway
2500
+ radius = N.sqrt( (StartXY[0]-CenterXY[0])**2 + (StartXY[1]-CenterXY[1])**2 )
2501
+ minX = CenterXY[0]-radius
2502
+ minY = CenterXY[1]-radius
2503
+ maxX = CenterXY[0]+radius
2504
+ maxY = CenterXY[1]+radius
2505
+ XY = [minX,minY]
2506
+ WH = [maxX-minX,maxY-minY]
2507
+
2508
+ self.XY = N.asarray( XY, float).reshape((2,))
2509
+ self.WH = N.asarray( WH, float).reshape((2,))
2510
+
2511
+ self.StartXY = N.asarray(StartXY, float).reshape((2,))
2512
+ self.CenterXY = N.asarray(CenterXY, float).reshape((2,))
2513
+ self.EndXY = N.asarray(EndXY, float).reshape((2,))
2514
+
2515
+ #self.BoundingBox = array((self.XY, (self.XY + self.WH)), Float)
2516
+ self.CalcBoundingBox()
2517
+
2518
+ #Finish the setup; allocate color,style etc.
2519
+ self.LineColor = LineColor
2520
+ self.LineStyle = LineStyle
2521
+ self.LineWidth = LineWidth
2522
+ self.FillColor = FillColor
2523
+ self.FillStyle = FillStyle
2524
+
2525
+ self.HitLineWidth = max(LineWidth,self.MinHitLineWidth)
2526
+
2527
+ self.SetPen(LineColor, LineStyle, LineWidth)
2528
+ self.SetBrush(FillColor, FillStyle) #Why isn't this working ???
2529
+
2530
+ def Move(self, Delta):
2531
+ """
2532
+ Move the object by delta
2533
+
2534
+ :param `Delta`: delta is a (dx, dy) pair. Ideally a `NumPy <http://www.numpy.org/>`_
2535
+ array of shape (2,)
2536
+
2537
+ """
2538
+
2539
+ Delta = N.asarray(Delta, float)
2540
+ self.XY += Delta
2541
+ self.StartXY += Delta
2542
+ self.CenterXY += Delta
2543
+ self.EndXY += Delta
2544
+ self.BoundingBox += Delta
2545
+
2546
+ if self._Canvas:
2547
+ self._Canvas.BoundingBoxDirty = True
2548
+
2549
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
2550
+ self.SetUpDraw(dc , WorldToPixel, ScaleWorldToPixel, HTdc)
2551
+ StartXY = WorldToPixel(self.StartXY)
2552
+ EndXY = WorldToPixel(self.EndXY)
2553
+ CenterXY = WorldToPixel(self.CenterXY)
2554
+
2555
+ dc.DrawArc(StartXY, EndXY, CenterXY)
2556
+ if HTdc and self.HitAble:
2557
+ HTdc.DrawArc(StartXY, EndXY, CenterXY)
2558
+
2559
+ def CalcBoundingBox(self):
2560
+ """Calculate the bounding box."""
2561
+ self.BoundingBox = BBox.asBBox( N.array((self.XY, (self.XY + self.WH) ),
2562
+ float) )
2563
+ if self._Canvas:
2564
+ self._Canvas.BoundingBoxDirty = True
2565
+
2566
+
2567
+ class PieChart(XYObjectMixin, LineOnlyMixin, DrawObject):
2568
+ """
2569
+ This is DrawObject for a pie chart
2570
+
2571
+ You can pass in a bunch of values, and it will draw a pie chart for
2572
+ you, and it will make the chart, scaling the size of each "slice" to
2573
+ match your values.
2574
+ """
2575
+
2576
+ ##fixme: this should be a longer and better designed set.
2577
+ ## Maybe one from: http://geography.uoregon.edu/datagraphics/color_scales.htm
2578
+ DefaultColorList = Colors.CategoricalColor1
2579
+ #["Red", "Green", "Blue", "Purple", "Yellow", "Cyan"]
2580
+
2581
+ def __init__(self,
2582
+ XY,
2583
+ Diameter,
2584
+ Values,
2585
+ FillColors=None,
2586
+ FillStyles=None,
2587
+ LineColor = None,
2588
+ LineStyle = "Solid",
2589
+ LineWidth = 1,
2590
+ Scaled = True,
2591
+ InForeground = False):
2592
+ """
2593
+ Default class constructor.
2594
+
2595
+ :param `XY`: The (x,y) coords of the center of the chart
2596
+ :param `Diameter`: The diamter of the chart in worls coords, unless you
2597
+ set "Scaled" to False, in which case it's in pixel coords.
2598
+ :param `Values`: sequence of values you want to make the chart of.
2599
+ :param `FillColors`: sequence of colors you want the slices. If
2600
+ None, it will choose (no guarantee you'll like them!)
2601
+ :param `FillStyles`: Fill style you want ("Solid", "Hash", etc)
2602
+ :param `LineColor`: Color of lines separating the slices
2603
+ :param `LineStyle`: style of lines separating the slices
2604
+ :param `LineWidth`: With of lines separating the slices
2605
+ :param `Scaled`: Do you want the pie to scale when zooming?
2606
+ or stay the same size in pixels?
2607
+ :param `InForeground`: Should it be on the foreground?
2608
+ """
2609
+ DrawObject.__init__(self, InForeground)
2610
+
2611
+ self.XY = N.asarray(XY, float).reshape( (2,) )
2612
+ self.Diameter = Diameter
2613
+ self.Values = N.asarray(Values, dtype=float).reshape((-1,1))
2614
+ if FillColors is None:
2615
+ FillColors = self.DefaultColorList[:len(Values)]
2616
+ if FillStyles is None:
2617
+ FillStyles = ['Solid'] * len(FillColors)
2618
+ self.FillColors = FillColors
2619
+ self.FillStyles = FillStyles
2620
+ self.LineColor = LineColor
2621
+ self.LineStyle = LineStyle
2622
+
2623
+ self.Scaled = Scaled
2624
+ self.InForeground = InForeground
2625
+
2626
+ self.SetPen(LineColor, LineStyle, LineWidth)
2627
+ self.SetBrushes()
2628
+ self.CalculatePoints()
2629
+
2630
+ def SetFillColors(self, FillColors):
2631
+ """
2632
+ Set the FillColors and update the Brushes.
2633
+
2634
+ :param `FillColors`: sequence of colors
2635
+ """
2636
+ self.FillColors = FillColors
2637
+ self.SetBrushes()
2638
+
2639
+ def SetFillStyles(self, FillStyles):
2640
+ """
2641
+ Set te FillStyles and update the Brushes.
2642
+
2643
+ :param `FillStyles`: Fill style you want ("Solid", "Hash", etc)
2644
+ """
2645
+ self.FillStyles = FillStyles
2646
+ self.SetBrushed()
2647
+
2648
+ def SetValues(self, Values):
2649
+ """
2650
+ Set the values and calculate the points.
2651
+
2652
+ :param `Values`: sequence of values you want to use for the chart
2653
+ """
2654
+ Values = N.asarray(Values, dtype=float).reshape((-1,1))
2655
+ self.Values = Values
2656
+ self.CalculatePoints()
2657
+
2658
+ def CalculatePoints(self):
2659
+ """Calculate the points."""
2660
+ # add the zero point to start
2661
+ Values = N.vstack( ( (0,), self.Values) )
2662
+ self.Angles = 360. * Values.cumsum()/Values.sum()
2663
+ self.CalcBoundingBox()
2664
+
2665
+ def SetBrushes(self):
2666
+ """Set the Brushes."""
2667
+ self.Brushes = []
2668
+ for FillColor, FillStyle in zip(self.FillColors, self.FillStyles):
2669
+ if FillColor is None or FillStyle is None:
2670
+ self.Brush = wx.TRANSPARENT_BRUSH
2671
+ else:
2672
+ self.Brushes.append(self.BrushList.setdefault( (FillColor, FillStyle),
2673
+ wx.Brush( FillColor, self.FillStyleList[FillStyle] )
2674
+ )
2675
+ )
2676
+ def CalcBoundingBox(self):
2677
+ """Calculate the bounding box."""
2678
+ if self.Scaled:
2679
+ self.BoundingBox = BBox.asBBox( ((self.XY-self.Diameter),(self.XY+self.Diameter)) )
2680
+ else:
2681
+ self.BoundingBox = BBox.asBBox((self.XY, self.XY))
2682
+ if self._Canvas:
2683
+ self._Canvas.BoundingBoxDirty = True
2684
+
2685
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel, HTdc=None):
2686
+ CenterXY = WorldToPixel(self.XY)
2687
+ if self.Scaled:
2688
+ Diameter = ScaleWorldToPixel( (self.Diameter,self.Diameter) )[0]
2689
+ else:
2690
+ Diameter = self.Diameter
2691
+ WH = N.array((Diameter,Diameter), dtype = float)
2692
+ Corner = CenterXY - (WH / 2)
2693
+ dc.SetPen(self.Pen)
2694
+ for i, brush in enumerate(self.Brushes):
2695
+ dc.SetBrush( brush )
2696
+ dc.DrawEllipticArc(Corner[0], Corner[1], WH[0], WH[1], self.Angles[i], self.Angles[i+1])
2697
+ if HTdc and self.HitAble:
2698
+ if self.Scaled:
2699
+ radius = (ScaleWorldToPixel(self.Diameter)/2)[0]# just the x-coord
2700
+ else:
2701
+ radius = self.Diameter/2
2702
+ HTdc.SetPen(self.HitPen)
2703
+ HTdc.SetBrush(self.HitBrush)
2704
+ HTdc.DrawCircle(CenterXY, radius)
2705
+
2706
+
2707
+ class Group(DrawObject):
2708
+ """
2709
+ A group of other FloatCanvas Objects
2710
+
2711
+ Not all DrawObject methods may apply here.
2712
+
2713
+ Note that if an object is in more than one group, it will get drawn more than once.
2714
+
2715
+ """
2716
+
2717
+ def __init__(self, ObjectList=[], InForeground=False, IsVisible=True):
2718
+ """
2719
+ Default class constructor.
2720
+
2721
+ :param list `ObjectList`: a list of :class:`DrawObject` to be grouped
2722
+ :param boolean `InForeground`: keep in foreground
2723
+ :param boolean `IsVisible`: keep it visible
2724
+
2725
+ """
2726
+ self.ObjectList = []
2727
+ DrawObject.__init__(self, InForeground, IsVisible)
2728
+
2729
+ # this one uses a proprty for _Canvas...
2730
+ self._Actual_Canvas = None
2731
+
2732
+ self.CalcBoundingBox()
2733
+ for obj in ObjectList:
2734
+ self.AddObject(obj)
2735
+ self.CalcBoundingBox()
2736
+
2737
+ ## re-define _Canvas property so that the sub-objects get set up right
2738
+ @property
2739
+ def _Canvas(self):
2740
+ """
2741
+ getter for the _Canvas property
2742
+ """
2743
+ return self._Actual_Canvas
2744
+
2745
+ @_Canvas.setter
2746
+ def _Canvas(self, canvas):
2747
+ """
2748
+ setter for Canvas property
2749
+ """
2750
+ self._Actual_Canvas = canvas
2751
+ for obj in self.ObjectList:
2752
+ obj._Canvas = canvas
2753
+
2754
+ def AddObject(self, obj):
2755
+ """
2756
+ Add an object to the group.
2757
+
2758
+ :param DrawObject `obj`: object to add
2759
+
2760
+ """
2761
+ self.ObjectList.append(obj)
2762
+ self.BoundingBox.Merge(obj.BoundingBox)
2763
+
2764
+ def AddObjects(self, Objects):
2765
+ """
2766
+ Add objects to the group.
2767
+
2768
+ :param list `Objects`: a list of :class:`DrawObject` to be grouped
2769
+
2770
+ """
2771
+ for o in Objects:
2772
+ self.AddObject(o)
2773
+
2774
+ def CalcBoundingBox(self):
2775
+ """Calculate the bounding box."""
2776
+ if self.ObjectList:
2777
+ BB = BBox.BBox(self.ObjectList[0].BoundingBox).copy()
2778
+ for obj in self.ObjectList[1:]:
2779
+ BB.Merge(obj.BoundingBox)
2780
+ else:
2781
+ BB = BBox.NullBBox()
2782
+ self.BoundingBox = BB
2783
+
2784
+ def SetColor(self, Color):
2785
+ """
2786
+ Set the Color
2787
+
2788
+ :param `Color`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
2789
+ for valid values
2790
+
2791
+ """
2792
+ for o in self.ObjectList:
2793
+ o.SetColor(Color)
2794
+
2795
+ def SetLineColor(self, Color):
2796
+ """
2797
+ Set the LineColor
2798
+
2799
+ :param `LineColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
2800
+ for valid values
2801
+
2802
+ """
2803
+ for o in self.ObjectList:
2804
+ o.SetLineColor(Color)
2805
+
2806
+ def SetLineStyle(self, LineStyle):
2807
+ """
2808
+ Set the LineStyle
2809
+
2810
+ :param `LineStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetLineStyle`
2811
+ for valid values
2812
+
2813
+ """
2814
+ for o in self.ObjectList:
2815
+ o.SetLineStyle(LineStyle)
2816
+
2817
+ def SetLineWidth(self, LineWidth):
2818
+ """
2819
+ Set the LineWidth
2820
+
2821
+ :param integer `LineWidth`: line width in pixels
2822
+
2823
+ """
2824
+ for o in self.ObjectList:
2825
+ o.SetLineWidth(LineWidth)
2826
+
2827
+ def SetFillColor(self, Color):
2828
+ """
2829
+ Set the FillColor
2830
+
2831
+ :param `FillColor`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetColor`
2832
+ for valid values
2833
+
2834
+ """
2835
+ for o in self.ObjectList:
2836
+ o.SetFillColor(Color)
2837
+
2838
+ def SetFillStyle(self, FillStyle):
2839
+ """
2840
+ Set the FillStyle
2841
+
2842
+ :param `FillStyle`: see :meth:`~lib.floatcanvas.FloatCanvas.DrawObject.SetFillStyle`
2843
+ for valid values
2844
+
2845
+ """
2846
+ for o in self.ObjectList:
2847
+ o.SetFillStyle(FillStyle)
2848
+
2849
+ def Move(self, Delta):
2850
+ """
2851
+ Moves the object by delta, where delta is a (dx, dy) pair.
2852
+
2853
+ :param `Delta`: is a (dx, dy) pair ideally a `NumPy <http://www.numpy.org/>`_
2854
+ array of shape (2, )
2855
+
2856
+ """
2857
+ for obj in self.ObjectList:
2858
+ obj.Move(Delta)
2859
+ self.BoundingBox += Delta
2860
+
2861
+ def Bind(self, Event, CallBackFun):
2862
+ """
2863
+ Bind an event to the Group object
2864
+
2865
+ :param `Event`: see below for supported event types
2866
+
2867
+ - EVT_FC_LEFT_DOWN
2868
+ - EVT_FC_LEFT_UP
2869
+ - EVT_FC_LEFT_DCLICK
2870
+ - EVT_FC_MIDDLE_DOWN
2871
+ - EVT_FC_MIDDLE_UP
2872
+ - EVT_FC_MIDDLE_DCLICK
2873
+ - EVT_FC_RIGHT_DOWN
2874
+ - EVT_FC_RIGHT_UP
2875
+ - EVT_FC_RIGHT_DCLICK
2876
+ - EVT_FC_ENTER_OBJECT
2877
+ - EVT_FC_LEAVE_OBJECT
2878
+
2879
+ :param `CallBackFun`: the call back function for the event
2880
+
2881
+
2882
+ """
2883
+ ## slight variation on DrawObject Bind Method:
2884
+ ## fixme: There is a lot of repeated code from the DrawObject method, but
2885
+ ## it all needs a lot of cleaning up anyway.
2886
+ self.CallBackFuncs[Event] = CallBackFun
2887
+ self.HitAble = True
2888
+ self._Canvas.UseHitTest = True
2889
+ if self.InForeground and self._Canvas._ForegroundHTBitmap is None:
2890
+ self._Canvas.MakeNewForegroundHTBitmap()
2891
+ elif self._Canvas._HTBitmap is None:
2892
+ self._Canvas.MakeNewHTBitmap()
2893
+ if not self.HitColor:
2894
+ if not self._Canvas.HitColorGenerator:
2895
+ self._Canvas.HitColorGenerator = _colorGenerator()
2896
+ # first call to prevent the background color from being used.
2897
+ if six.PY2:
2898
+ self._Canvas.HitColorGenerator.next()
2899
+ else:
2900
+ next(self._Canvas.HitColorGenerator)
2901
+ # Set all contained objects to the same Hit color:
2902
+ if six.PY2:
2903
+ self.HitColor = self._Canvas.HitColorGenerator.next()
2904
+ else:
2905
+ self.HitColor = next(self._Canvas.HitColorGenerator)
2906
+ self._ChangeChildrenHitColor(self.ObjectList)
2907
+ # put the object in the hit dict, indexed by it's color
2908
+ if not self._Canvas.HitDict:
2909
+ self._Canvas.MakeHitDict()
2910
+ self._Canvas.HitDict[Event][self.HitColor] = (self)
2911
+
2912
+ def _ChangeChildrenHitColor(self, objlist):
2913
+ for obj in objlist:
2914
+ obj.SetHitPen(self.HitColor, self.HitLineWidth)
2915
+ obj.SetHitBrush(self.HitColor)
2916
+ obj.HitAble = True
2917
+
2918
+ if isinstance(obj, Group):
2919
+ self._ChangeChildrenHitColor(obj.ObjectList)
2920
+
2921
+ def _Draw(self, dc , WorldToPixel, ScaleWorldToPixel = None, HTdc=None):
2922
+ for obj in self.ObjectList:
2923
+ obj._Draw(dc, WorldToPixel, ScaleWorldToPixel, HTdc)