wxPython 4.3.2__cp315-cp315-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (472) hide show
  1. wx/WebView2Loader.dll +0 -0
  2. wx/__init__.py +22 -0
  3. wx/__init__.pyi +10 -0
  4. wx/__version__.py +9 -0
  5. wx/__version__.pyi +15 -0
  6. wx/_adv.cp315-win_amd64.pyd +0 -0
  7. wx/_aui.cp315-win_amd64.pyd +0 -0
  8. wx/_core.cp315-win_amd64.pyd +0 -0
  9. wx/_dataview.cp315-win_amd64.pyd +0 -0
  10. wx/_glcanvas.cp315-win_amd64.pyd +0 -0
  11. wx/_grid.cp315-win_amd64.pyd +0 -0
  12. wx/_html.cp315-win_amd64.pyd +0 -0
  13. wx/_html2.cp315-win_amd64.pyd +0 -0
  14. wx/_media.cp315-win_amd64.pyd +0 -0
  15. wx/_msw.cp315-win_amd64.pyd +0 -0
  16. wx/_propgrid.cp315-win_amd64.pyd +0 -0
  17. wx/_ribbon.cp315-win_amd64.pyd +0 -0
  18. wx/_richtext.cp315-win_amd64.pyd +0 -0
  19. wx/_stc.cp315-win_amd64.pyd +0 -0
  20. wx/_xml.cp315-win_amd64.pyd +0 -0
  21. wx/_xrc.cp315-win_amd64.pyd +0 -0
  22. wx/adv.py +127 -0
  23. wx/adv.pyi +5931 -0
  24. wx/aui.py +70 -0
  25. wx/aui.pyi +4805 -0
  26. wx/core.py +3417 -0
  27. wx/core.pyi +62949 -0
  28. wx/dataview.py +176 -0
  29. wx/dataview.pyi +3828 -0
  30. wx/gizmos.py +18 -0
  31. wx/glcanvas.py +13 -0
  32. wx/glcanvas.pyi +544 -0
  33. wx/grid.py +237 -0
  34. wx/grid.pyi +5678 -0
  35. wx/html.py +38 -0
  36. wx/html.pyi +3283 -0
  37. wx/html2.py +46 -0
  38. wx/html2.pyi +1301 -0
  39. wx/include/wxPython/sip.h +1938 -0
  40. wx/include/wxPython/wxpy_api.h +418 -0
  41. wx/lib/CDate.py +201 -0
  42. wx/lib/ClickableHtmlWindow.py +57 -0
  43. wx/lib/__init__.py +0 -0
  44. wx/lib/activex.py +178 -0
  45. wx/lib/activexwrapper.py +153 -0
  46. wx/lib/agw/__init__.py +128 -0
  47. wx/lib/agw/advancedsplash.py +563 -0
  48. wx/lib/agw/aquabutton.py +1127 -0
  49. wx/lib/agw/artmanager.py +2110 -0
  50. wx/lib/agw/aui/__init__.py +295 -0
  51. wx/lib/agw/aui/aui_constants.py +2616 -0
  52. wx/lib/agw/aui/aui_switcherdialog.py +1232 -0
  53. wx/lib/agw/aui/aui_utilities.py +648 -0
  54. wx/lib/agw/aui/auibar.py +4045 -0
  55. wx/lib/agw/aui/auibook.py +6288 -0
  56. wx/lib/agw/aui/dockart.py +1198 -0
  57. wx/lib/agw/aui/framemanager.py +10485 -0
  58. wx/lib/agw/aui/tabart.py +2749 -0
  59. wx/lib/agw/aui/tabmdi.py +679 -0
  60. wx/lib/agw/balloontip.py +1157 -0
  61. wx/lib/agw/buttonpanel.py +2787 -0
  62. wx/lib/agw/cubecolourdialog.py +3529 -0
  63. wx/lib/agw/customtreectrl.py +9908 -0
  64. wx/lib/agw/data/ShortcutEditor_1.png +0 -0
  65. wx/lib/agw/data/ShortcutEditor_1_thumb.png +0 -0
  66. wx/lib/agw/data/ShortcutEditor_2.png +0 -0
  67. wx/lib/agw/data/ShortcutEditor_2_thumb.png +0 -0
  68. wx/lib/agw/data/ShortcutEditor_3.png +0 -0
  69. wx/lib/agw/data/ShortcutEditor_3_thumb.png +0 -0
  70. wx/lib/agw/data/ShortcutEditor_4.png +0 -0
  71. wx/lib/agw/data/ShortcutEditor_4_thumb.png +0 -0
  72. wx/lib/agw/data/default_help_text.html +105 -0
  73. wx/lib/agw/flatmenu.py +7392 -0
  74. wx/lib/agw/flatnotebook.py +6669 -0
  75. wx/lib/agw/floatspin.py +1820 -0
  76. wx/lib/agw/fmcustomizedlg.py +535 -0
  77. wx/lib/agw/fmresources.py +407 -0
  78. wx/lib/agw/foldpanelbar.py +2282 -0
  79. wx/lib/agw/fourwaysplitter.py +1130 -0
  80. wx/lib/agw/genericmessagedialog.py +1549 -0
  81. wx/lib/agw/gradientbutton.py +731 -0
  82. wx/lib/agw/hyperlink.py +664 -0
  83. wx/lib/agw/hypertreelist.py +5756 -0
  84. wx/lib/agw/infobar.py +885 -0
  85. wx/lib/agw/knobctrl.py +944 -0
  86. wx/lib/agw/labelbook.py +3028 -0
  87. wx/lib/agw/multidirdialog.py +581 -0
  88. wx/lib/agw/peakmeter.py +1028 -0
  89. wx/lib/agw/persist/__init__.py +188 -0
  90. wx/lib/agw/persist/persist_constants.py +283 -0
  91. wx/lib/agw/persist/persist_handlers.py +2614 -0
  92. wx/lib/agw/persist/persistencemanager.py +863 -0
  93. wx/lib/agw/piectrl.py +1082 -0
  94. wx/lib/agw/pybusyinfo.py +399 -0
  95. wx/lib/agw/pycollapsiblepane.py +940 -0
  96. wx/lib/agw/pygauge.py +570 -0
  97. wx/lib/agw/pyprogress.py +916 -0
  98. wx/lib/agw/ribbon/__init__.py +198 -0
  99. wx/lib/agw/ribbon/art.py +219 -0
  100. wx/lib/agw/ribbon/art_aui.py +1283 -0
  101. wx/lib/agw/ribbon/art_default.py +81 -0
  102. wx/lib/agw/ribbon/art_internal.py +248 -0
  103. wx/lib/agw/ribbon/art_msw.py +2735 -0
  104. wx/lib/agw/ribbon/art_osx.py +52 -0
  105. wx/lib/agw/ribbon/bar.py +1259 -0
  106. wx/lib/agw/ribbon/buttonbar.py +1317 -0
  107. wx/lib/agw/ribbon/control.py +205 -0
  108. wx/lib/agw/ribbon/gallery.py +973 -0
  109. wx/lib/agw/ribbon/page.py +946 -0
  110. wx/lib/agw/ribbon/panel.py +1170 -0
  111. wx/lib/agw/ribbon/toolbar.py +1441 -0
  112. wx/lib/agw/rulerctrl.py +1885 -0
  113. wx/lib/agw/scrolledthumbnail.py +2116 -0
  114. wx/lib/agw/shapedbutton.py +1809 -0
  115. wx/lib/agw/shortcuteditor.py +2642 -0
  116. wx/lib/agw/speedmeter.py +1800 -0
  117. wx/lib/agw/supertooltip.py +1443 -0
  118. wx/lib/agw/thumbnailctrl.py +529 -0
  119. wx/lib/agw/toasterbox.py +1327 -0
  120. wx/lib/agw/ultimatelistctrl.py +13671 -0
  121. wx/lib/agw/xlsgrid.py +2111 -0
  122. wx/lib/agw/zoombar.py +1336 -0
  123. wx/lib/analogclock/__init__.py +140 -0
  124. wx/lib/analogclock/analogclock.py +630 -0
  125. wx/lib/analogclock/helpers.py +986 -0
  126. wx/lib/analogclock/lib_setup/__init__.py +0 -0
  127. wx/lib/analogclock/lib_setup/buttontreectrlpanel.py +297 -0
  128. wx/lib/analogclock/lib_setup/fontselect.py +57 -0
  129. wx/lib/analogclock/setup.py +490 -0
  130. wx/lib/analogclock/styles.py +47 -0
  131. wx/lib/anchors.py +103 -0
  132. wx/lib/art/__init__.py +4 -0
  133. wx/lib/art/flagart.py +1583 -0
  134. wx/lib/art/img2pyartprov.py +56 -0
  135. wx/lib/busy.py +152 -0
  136. wx/lib/buttons.py +1140 -0
  137. wx/lib/calendar.py +1596 -0
  138. wx/lib/checkbox.py +837 -0
  139. wx/lib/colourchooser/__init__.py +36 -0
  140. wx/lib/colourchooser/canvas.py +145 -0
  141. wx/lib/colourchooser/intl.py +24 -0
  142. wx/lib/colourchooser/pycolourbox.py +89 -0
  143. wx/lib/colourchooser/pycolourchooser.py +626 -0
  144. wx/lib/colourchooser/pycolourslider.py +98 -0
  145. wx/lib/colourchooser/pypalette.py +208 -0
  146. wx/lib/colourdb.py +740 -0
  147. wx/lib/colourselect.py +385 -0
  148. wx/lib/colourutils.py +118 -0
  149. wx/lib/combotreebox.py +944 -0
  150. wx/lib/delayedresult.py +420 -0
  151. wx/lib/dialogs.py +510 -0
  152. wx/lib/docview.py +3210 -0
  153. wx/lib/dragscroller.py +79 -0
  154. wx/lib/editor/README.txt +77 -0
  155. wx/lib/editor/__init__.py +24 -0
  156. wx/lib/editor/editor.py +974 -0
  157. wx/lib/editor/images.py +15 -0
  158. wx/lib/editor/selection.py +44 -0
  159. wx/lib/embeddedimage.py +76 -0
  160. wx/lib/eventStack.py +136 -0
  161. wx/lib/eventwatcher.py +440 -0
  162. wx/lib/evtmgr.py +521 -0
  163. wx/lib/expando.py +393 -0
  164. wx/lib/fancytext.py +494 -0
  165. wx/lib/filebrowsebutton.py +461 -0
  166. wx/lib/flashwin.py +262 -0
  167. wx/lib/flashwin_old.py +651 -0
  168. wx/lib/floatcanvas/FCEvents.py +53 -0
  169. wx/lib/floatcanvas/FCObjects.py +2910 -0
  170. wx/lib/floatcanvas/FloatCanvas.py +1025 -0
  171. wx/lib/floatcanvas/GUIMode.py +396 -0
  172. wx/lib/floatcanvas/NavCanvas.py +162 -0
  173. wx/lib/floatcanvas/Resources.py +319 -0
  174. wx/lib/floatcanvas/ScreenShot.py +1788 -0
  175. wx/lib/floatcanvas/Utilities/BBox.py +313 -0
  176. wx/lib/floatcanvas/Utilities/Colors.py +137 -0
  177. wx/lib/floatcanvas/Utilities/GUI.py +91 -0
  178. wx/lib/floatcanvas/Utilities/__init__.py +7 -0
  179. wx/lib/floatcanvas/__init__.py +124 -0
  180. wx/lib/foldmenu.py +89 -0
  181. wx/lib/gestures.py +310 -0
  182. wx/lib/gizmos/__init__.py +18 -0
  183. wx/lib/gizmos/dynamicsash.py +1202 -0
  184. wx/lib/gizmos/ledctrl.py +299 -0
  185. wx/lib/gizmos/treelistctrl.py +87 -0
  186. wx/lib/graphics.py +1942 -0
  187. wx/lib/gridmovers.py +516 -0
  188. wx/lib/iewin.py +249 -0
  189. wx/lib/iewin_old.py +894 -0
  190. wx/lib/imagebrowser.py +853 -0
  191. wx/lib/imageutils.py +163 -0
  192. wx/lib/infoframe.py +490 -0
  193. wx/lib/inspection.py +1254 -0
  194. wx/lib/intctrl.py +990 -0
  195. wx/lib/itemspicker.py +256 -0
  196. wx/lib/langlistctrl.py +480 -0
  197. wx/lib/layoutf.py +271 -0
  198. wx/lib/masked/__init__.py +27 -0
  199. wx/lib/masked/combobox.py +839 -0
  200. wx/lib/masked/ctrl.py +108 -0
  201. wx/lib/masked/ipaddrctrl.py +241 -0
  202. wx/lib/masked/maskededit.py +7262 -0
  203. wx/lib/masked/numctrl.py +2000 -0
  204. wx/lib/masked/textctrl.py +465 -0
  205. wx/lib/masked/timectrl.py +1465 -0
  206. wx/lib/mixins/__init__.py +17 -0
  207. wx/lib/mixins/grid.py +47 -0
  208. wx/lib/mixins/gridlabelrenderer.py +277 -0
  209. wx/lib/mixins/imagelist.py +77 -0
  210. wx/lib/mixins/inspection.py +184 -0
  211. wx/lib/mixins/listctrl.py +893 -0
  212. wx/lib/mixins/rubberband.py +403 -0
  213. wx/lib/mixins/treemixin.py +678 -0
  214. wx/lib/msgpanel.py +95 -0
  215. wx/lib/multisash.py +746 -0
  216. wx/lib/myole4ax.idl +178 -0
  217. wx/lib/myole4ax.tlb +0 -0
  218. wx/lib/newevent.py +229 -0
  219. wx/lib/newevent.pyi +25 -0
  220. wx/lib/nvdlg.py +156 -0
  221. wx/lib/ogl/__init__.py +13 -0
  222. wx/lib/ogl/basic.py +3989 -0
  223. wx/lib/ogl/bmpshape.py +86 -0
  224. wx/lib/ogl/canvas.py +467 -0
  225. wx/lib/ogl/composit.py +1576 -0
  226. wx/lib/ogl/diagram.py +230 -0
  227. wx/lib/ogl/divided.py +482 -0
  228. wx/lib/ogl/drawn.py +898 -0
  229. wx/lib/ogl/lines.py +1809 -0
  230. wx/lib/ogl/oglmisc.py +607 -0
  231. wx/lib/pdfviewer/__init__.py +113 -0
  232. wx/lib/pdfviewer/bitmaps/ArrowLeft.png +0 -0
  233. wx/lib/pdfviewer/bitmaps/ArrowRight.png +0 -0
  234. wx/lib/pdfviewer/bitmaps/DirectionH.png +0 -0
  235. wx/lib/pdfviewer/bitmaps/DirectionV.png +0 -0
  236. wx/lib/pdfviewer/bitmaps/PlayerFirst.png +0 -0
  237. wx/lib/pdfviewer/bitmaps/PlayerLast.png +0 -0
  238. wx/lib/pdfviewer/bitmaps/PlayerNext.png +0 -0
  239. wx/lib/pdfviewer/bitmaps/PlayerPrev.png +0 -0
  240. wx/lib/pdfviewer/bitmaps/Printer.png +0 -0
  241. wx/lib/pdfviewer/bitmaps/ReadMe.txt +28 -0
  242. wx/lib/pdfviewer/bitmaps/Save.png +0 -0
  243. wx/lib/pdfviewer/bitmaps/ZoomIn.png +0 -0
  244. wx/lib/pdfviewer/bitmaps/ZoomOut.png +0 -0
  245. wx/lib/pdfviewer/bitmaps/encode_bitmaps.py +37 -0
  246. wx/lib/pdfviewer/buttonpanel.py +285 -0
  247. wx/lib/pdfviewer/images.py +240 -0
  248. wx/lib/pdfviewer/viewer.py +1118 -0
  249. wx/lib/pdfwin.py +295 -0
  250. wx/lib/pdfwin_old.py +789 -0
  251. wx/lib/platebtn.py +789 -0
  252. wx/lib/plot/CHANGELOG.md +150 -0
  253. wx/lib/plot/README.md +16 -0
  254. wx/lib/plot/__init__.py +46 -0
  255. wx/lib/plot/__main__.py +5 -0
  256. wx/lib/plot/examples/__init__.py +0 -0
  257. wx/lib/plot/examples/demo.py +1010 -0
  258. wx/lib/plot/examples/simple_example.py +56 -0
  259. wx/lib/plot/plotcanvas.py +2985 -0
  260. wx/lib/plot/polyobjects.py +1524 -0
  261. wx/lib/plot/utils.py +334 -0
  262. wx/lib/popupctl.py +251 -0
  263. wx/lib/printout.py +1155 -0
  264. wx/lib/progressindicator.py +151 -0
  265. wx/lib/pubsub/LICENSE_BSD_Simple.txt +23 -0
  266. wx/lib/pubsub/README_WxPython.txt +22 -0
  267. wx/lib/pubsub/RELEASE_NOTES.txt +71 -0
  268. wx/lib/pubsub/__init__.py +25 -0
  269. wx/lib/pubsub/core/__init__.py +92 -0
  270. wx/lib/pubsub/core/arg1/__init__.py +16 -0
  271. wx/lib/pubsub/core/arg1/listenerimpl.py +97 -0
  272. wx/lib/pubsub/core/arg1/publisher.py +40 -0
  273. wx/lib/pubsub/core/arg1/publishermixin.py +34 -0
  274. wx/lib/pubsub/core/arg1/topicargspecimpl.py +66 -0
  275. wx/lib/pubsub/core/arg1/topicmgrimpl.py +19 -0
  276. wx/lib/pubsub/core/callables.py +198 -0
  277. wx/lib/pubsub/core/imp2.py +62 -0
  278. wx/lib/pubsub/core/itopicdefnprovider.py +0 -0
  279. wx/lib/pubsub/core/kwargs/__init__.py +16 -0
  280. wx/lib/pubsub/core/kwargs/datamsg.py +27 -0
  281. wx/lib/pubsub/core/kwargs/listenerimpl.py +93 -0
  282. wx/lib/pubsub/core/kwargs/publisher.py +77 -0
  283. wx/lib/pubsub/core/kwargs/publishermixin.py +65 -0
  284. wx/lib/pubsub/core/kwargs/topicargspecimpl.py +216 -0
  285. wx/lib/pubsub/core/kwargs/topicmgrimpl.py +13 -0
  286. wx/lib/pubsub/core/listener.py +40 -0
  287. wx/lib/pubsub/core/listenerbase.py +185 -0
  288. wx/lib/pubsub/core/notificationmgr.py +185 -0
  289. wx/lib/pubsub/core/publisherbase.py +189 -0
  290. wx/lib/pubsub/core/topicargspec.py +77 -0
  291. wx/lib/pubsub/core/topicdefnprovider.py +631 -0
  292. wx/lib/pubsub/core/topicexc.py +72 -0
  293. wx/lib/pubsub/core/topicmgr.py +454 -0
  294. wx/lib/pubsub/core/topicobj.py +472 -0
  295. wx/lib/pubsub/core/topictreetraverser.py +143 -0
  296. wx/lib/pubsub/core/topicutils.py +119 -0
  297. wx/lib/pubsub/core/treeconfig.py +21 -0
  298. wx/lib/pubsub/core/validatedefnargs.py +29 -0
  299. wx/lib/pubsub/core/weakmethod.py +102 -0
  300. wx/lib/pubsub/policies.py +24 -0
  301. wx/lib/pubsub/pub.py +199 -0
  302. wx/lib/pubsub/setuparg1.py +47 -0
  303. wx/lib/pubsub/setupkwargs.py +29 -0
  304. wx/lib/pubsub/utils/__init__.py +27 -0
  305. wx/lib/pubsub/utils/exchandling.py +100 -0
  306. wx/lib/pubsub/utils/misc.py +99 -0
  307. wx/lib/pubsub/utils/notification.py +331 -0
  308. wx/lib/pubsub/utils/topictreeprinter.py +195 -0
  309. wx/lib/pubsub/utils/xmltopicdefnprovider.py +286 -0
  310. wx/lib/pydocview.py +3300 -0
  311. wx/lib/rcsizer.py +227 -0
  312. wx/lib/resizewidget.py +357 -0
  313. wx/lib/scrolledpanel.py +243 -0
  314. wx/lib/sheet.py +350 -0
  315. wx/lib/sized_controls.py +691 -0
  316. wx/lib/softwareupdate.py +355 -0
  317. wx/lib/splitter.py +925 -0
  318. wx/lib/statbmp.py +199 -0
  319. wx/lib/stattext.py +321 -0
  320. wx/lib/throbber.py +424 -0
  321. wx/lib/ticker.py +306 -0
  322. wx/lib/ticker_xrc.py +48 -0
  323. wx/lib/utils.py +89 -0
  324. wx/lib/wordwrap.py +97 -0
  325. wx/lib/wxcairo/__init__.py +139 -0
  326. wx/lib/wxcairo/wx_cairocffi.py +200 -0
  327. wx/lib/wxcairo/wx_pycairo.py +455 -0
  328. wx/lib/wxpTag.py +274 -0
  329. wx/libcairo-2.dll +0 -0
  330. wx/locale/af/LC_MESSAGES/wxstd.mo +0 -0
  331. wx/locale/an/LC_MESSAGES/wxstd.mo +0 -0
  332. wx/locale/ar/LC_MESSAGES/wxstd.mo +0 -0
  333. wx/locale/ca/LC_MESSAGES/wxstd.mo +0 -0
  334. wx/locale/ca@valencia/LC_MESSAGES/wxstd.mo +0 -0
  335. wx/locale/co/LC_MESSAGES/wxstd.mo +0 -0
  336. wx/locale/cs/LC_MESSAGES/wxstd.mo +0 -0
  337. wx/locale/da/LC_MESSAGES/wxstd.mo +0 -0
  338. wx/locale/de/LC_MESSAGES/wxstd.mo +0 -0
  339. wx/locale/el/LC_MESSAGES/wxstd.mo +0 -0
  340. wx/locale/es/LC_MESSAGES/wxstd.mo +0 -0
  341. wx/locale/eu/LC_MESSAGES/wxstd.mo +0 -0
  342. wx/locale/fa_IR/LC_MESSAGES/wxstd.mo +0 -0
  343. wx/locale/fi/LC_MESSAGES/wxstd.mo +0 -0
  344. wx/locale/fr/LC_MESSAGES/wxstd.mo +0 -0
  345. wx/locale/gl_ES/LC_MESSAGES/wxstd.mo +0 -0
  346. wx/locale/hi/LC_MESSAGES/wxstd.mo +0 -0
  347. wx/locale/hr/LC_MESSAGES/wxstd.mo +0 -0
  348. wx/locale/hu/LC_MESSAGES/wxstd.mo +0 -0
  349. wx/locale/id/LC_MESSAGES/wxstd.mo +0 -0
  350. wx/locale/it/LC_MESSAGES/wxstd.mo +0 -0
  351. wx/locale/ja/LC_MESSAGES/wxstd.mo +0 -0
  352. wx/locale/ka/LC_MESSAGES/wxstd.mo +0 -0
  353. wx/locale/ko_KR/LC_MESSAGES/wxstd.mo +0 -0
  354. wx/locale/lt/LC_MESSAGES/wxstd.mo +0 -0
  355. wx/locale/lv/LC_MESSAGES/wxstd.mo +0 -0
  356. wx/locale/ms/LC_MESSAGES/wxstd.mo +0 -0
  357. wx/locale/nb/LC_MESSAGES/wxstd.mo +0 -0
  358. wx/locale/ne/LC_MESSAGES/wxstd.mo +0 -0
  359. wx/locale/nl/LC_MESSAGES/wxstd.mo +0 -0
  360. wx/locale/pl/LC_MESSAGES/wxstd.mo +0 -0
  361. wx/locale/pt/LC_MESSAGES/wxstd.mo +0 -0
  362. wx/locale/pt_BR/LC_MESSAGES/wxstd.mo +0 -0
  363. wx/locale/ro/LC_MESSAGES/wxstd.mo +0 -0
  364. wx/locale/ru/LC_MESSAGES/wxstd.mo +0 -0
  365. wx/locale/sk/LC_MESSAGES/wxstd.mo +0 -0
  366. wx/locale/sl/LC_MESSAGES/wxstd.mo +0 -0
  367. wx/locale/sq/LC_MESSAGES/wxstd.mo +0 -0
  368. wx/locale/sr/LC_MESSAGES/wxstd.mo +0 -0
  369. wx/locale/sv/LC_MESSAGES/wxstd.mo +0 -0
  370. wx/locale/ta/LC_MESSAGES/wxstd.mo +0 -0
  371. wx/locale/tr/LC_MESSAGES/wxstd.mo +0 -0
  372. wx/locale/uk/LC_MESSAGES/wxstd.mo +0 -0
  373. wx/locale/vi/LC_MESSAGES/wxstd.mo +0 -0
  374. wx/locale/zh_CN/LC_MESSAGES/wxstd.mo +0 -0
  375. wx/locale/zh_TW/LC_MESSAGES/wxstd.mo +0 -0
  376. wx/media.py +30 -0
  377. wx/media.pyi +272 -0
  378. wx/msw.py +16 -0
  379. wx/msw.pyi +91 -0
  380. wx/propgrid.py +498 -0
  381. wx/propgrid.pyi +7427 -0
  382. wx/py/CHANGES.txt +796 -0
  383. wx/py/Py.ico +0 -0
  384. wx/py/PyAlaCarte.py +34 -0
  385. wx/py/PyAlaMode.py +34 -0
  386. wx/py/PyAlaModeTest.py +33 -0
  387. wx/py/PyCrust.ico +0 -0
  388. wx/py/PyCrust.py +78 -0
  389. wx/py/PyCrust_16.png +0 -0
  390. wx/py/PyCrust_32.png +0 -0
  391. wx/py/PyFilling.py +35 -0
  392. wx/py/PyShell.py +78 -0
  393. wx/py/PySlices.ico +0 -0
  394. wx/py/PySlices.py +98 -0
  395. wx/py/PySlicesShell.py +94 -0
  396. wx/py/PySlices_16.png +0 -0
  397. wx/py/PySlices_32.png +0 -0
  398. wx/py/PyWrap.py +52 -0
  399. wx/py/README.txt +77 -0
  400. wx/py/__init__.py +20 -0
  401. wx/py/buffer.py +136 -0
  402. wx/py/crust.py +403 -0
  403. wx/py/crustslices.py +403 -0
  404. wx/py/dispatcher.py +259 -0
  405. wx/py/document.py +37 -0
  406. wx/py/editor.py +844 -0
  407. wx/py/editwindow.py +316 -0
  408. wx/py/filling.py +358 -0
  409. wx/py/frame.py +976 -0
  410. wx/py/images.py +212 -0
  411. wx/py/interpreter.py +161 -0
  412. wx/py/introspect.py +402 -0
  413. wx/py/magic.py +98 -0
  414. wx/py/parse.py +134 -0
  415. wx/py/path.py +36 -0
  416. wx/py/pseudo.py +99 -0
  417. wx/py/shell.py +1579 -0
  418. wx/py/sliceshell.py +3805 -0
  419. wx/py/tests/test_interpreter.py +71 -0
  420. wx/py/tests/test_introspect.py +810 -0
  421. wx/py/tests/test_pseudo.py +70 -0
  422. wx/py/tests/test_version.py +36 -0
  423. wx/py/tests/testall.py +22 -0
  424. wx/py/version.py +7 -0
  425. wx/py.typed +0 -0
  426. wx/ribbon.py +48 -0
  427. wx/ribbon.pyi +3099 -0
  428. wx/richtext.py +141 -0
  429. wx/richtext.pyi +13581 -0
  430. wx/siplib.cp315-win_amd64.pyd +0 -0
  431. wx/siplib.pyi +19 -0
  432. wx/stc.py +59 -0
  433. wx/stc.pyi +9918 -0
  434. wx/svg/__init__.py +363 -0
  435. wx/svg/_nanosvg.cp315-win_amd64.pyd +0 -0
  436. wx/tools/__init__.py +18 -0
  437. wx/tools/dbg.py +268 -0
  438. wx/tools/genaxmodule.py +50 -0
  439. wx/tools/helpviewer.py +92 -0
  440. wx/tools/img2img.py +85 -0
  441. wx/tools/img2png.py +54 -0
  442. wx/tools/img2py.py +306 -0
  443. wx/tools/img2xpm.py +54 -0
  444. wx/tools/pywxrc.py +951 -0
  445. wx/tools/wxget.py +254 -0
  446. wx/tools/wxget_docs_demo.py +183 -0
  447. wx/wxbase334u_net_vc140_x64.dll +0 -0
  448. wx/wxbase334u_vc140_x64.dll +0 -0
  449. wx/wxbase334u_xml_vc140_x64.dll +0 -0
  450. wx/wxmsw334u_adv_vc140_x64.dll +0 -0
  451. wx/wxmsw334u_aui_vc140_x64.dll +0 -0
  452. wx/wxmsw334u_core_vc140_x64.dll +0 -0
  453. wx/wxmsw334u_gl_vc140_x64.dll +0 -0
  454. wx/wxmsw334u_html_vc140_x64.dll +0 -0
  455. wx/wxmsw334u_media_vc140_x64.dll +0 -0
  456. wx/wxmsw334u_propgrid_vc140_x64.dll +0 -0
  457. wx/wxmsw334u_qa_vc140_x64.dll +0 -0
  458. wx/wxmsw334u_ribbon_vc140_x64.dll +0 -0
  459. wx/wxmsw334u_richtext_vc140_x64.dll +0 -0
  460. wx/wxmsw334u_stc_vc140_x64.dll +0 -0
  461. wx/wxmsw334u_webview_vc140_x64.dll +0 -0
  462. wx/wxmsw334u_xrc_vc140_x64.dll +0 -0
  463. wx/xml.py +18 -0
  464. wx/xml.pyi +728 -0
  465. wx/xrc.py +68 -0
  466. wx/xrc.pyi +896 -0
  467. wxpython-4.3.2.dist-info/METADATA +71 -0
  468. wxpython-4.3.2.dist-info/RECORD +472 -0
  469. wxpython-4.3.2.dist-info/WHEEL +5 -0
  470. wxpython-4.3.2.dist-info/entry_points.txt +13 -0
  471. wxpython-4.3.2.dist-info/licenses/LICENSE.txt +610 -0
  472. wxpython-4.3.2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,3529 @@
1
+ # --------------------------------------------------------------------------- #
2
+ # CUBECOLOURDIALOG Widget wxPython IMPLEMENTATION
3
+ #
4
+ # Python Code By:
5
+ #
6
+ # Andrea Gavana, @ 16 Aug 2007
7
+ # Latest Revision: 19 Dec 2012, 21.00 GMT
8
+ #
9
+ #
10
+ # TODO List
11
+ #
12
+ # 1. Find A Way To Reduce Flickering On The 2 ColourPanels;
13
+ #
14
+ # 2. See Why wx.GCDC Doesn't Work As I Thought (!). It Looks Slow As A Turtle,
15
+ # But Probably I Am Doing Something Wrong While Painting The Alpha Textures.
16
+ #
17
+ #
18
+ # For All Kind Of Problems, Requests Of Enhancements And Bug Reports, Please
19
+ # Write To Me At:
20
+ #
21
+ # andrea.gavana@gmail.com
22
+ # andrea.gavana@maerskoil.com
23
+ #
24
+ # Or, Obviously, To The wxPython Mailing List!!!
25
+ #
26
+ # Tags: phoenix-port, unittest, documented, py3-port
27
+ #
28
+ # End Of Comments
29
+ # --------------------------------------------------------------------------- #
30
+
31
+ """
32
+ :class:`~wx.lib.agw.cubecolourdialog.CubeColourDialog` is an alternative implementation of :class:`wx.ColourDialog`.
33
+
34
+
35
+ Description
36
+ ===========
37
+
38
+ The :class:`CubeColourDialog` is an alternative implementation of :class:`wx.ColourDialog`, and it
39
+ offers different functionalities with respect to the default wxPython one. It
40
+ can be used as a replacement of :class:`wx.ColourDialog` with exactly the same syntax and
41
+ methods.
42
+
43
+ Some features:
44
+
45
+ - RGB components may be controlled using spin controls or with mouse gestures
46
+ on a 3D RGB cube, with the 3 components laying on the X, Y, Z axes;
47
+ - HSB components may be controlled using spin controls or with mouse gestures
48
+ on a 2D colour wheel;
49
+ - Brightness has its own vertical slider to play with;
50
+ - The colour alpha channel can be controlled using another vertical slider, or
51
+ via spin control;
52
+ - The colour alpha channel controls can be completely hidden at startup or the
53
+ choice to use the alpha channel can be left to the user while playing with the
54
+ dialog, via a simple :class:`CheckBox`;
55
+ - The "old colour" and "new colour" are displayed in two small custom panel,
56
+ which support alpha transparency and texture;
57
+ - :class:`CubeColourDialog` displays also the HTML colour code in hexadecimal format;
58
+ - When available, a corresponding "Web Safe" colour is generated using a 500
59
+ web colours "database" (a dictionary inside the widget source code). Web Safe
60
+ colours are recognized by all the browsers;
61
+ - When available, a corresponding "HTML name" for the selected colour is displayed,
62
+ by using the same 500 web colours "database";
63
+ - When available, a corresponding "Microsoft Access Code" for the selected colour
64
+ is displayed, by using the same 500 web colours "database".
65
+
66
+ And much more.
67
+
68
+
69
+ Usage
70
+ =====
71
+
72
+ Usage example::
73
+
74
+ import wx
75
+ import wx.lib.agw.cubecolourdialog as CCD
76
+
77
+ # Our normal wxApp-derived class, as usual
78
+ app = wx.App(0)
79
+
80
+ colourData = wx.ColourData()
81
+ dlg = CCD.CubeColourDialog(None, colourData)
82
+
83
+ if dlg.ShowModal() == wx.ID_OK:
84
+
85
+ # If the user selected OK, then the dialog's wx.ColourData will
86
+ # contain valid information. Fetch the data ...
87
+ colourData = dlg.GetColourData()
88
+ h, s, v, a = dlg.GetHSVAColour()
89
+
90
+ # ... then do something with it. The actual colour data will be
91
+ # returned as a three-tuple (r, g, b) in this particular case.
92
+ colour = colourData.GetColour()
93
+ r, g, b, alpha = colour.Red(), colour.Green(), colour.Blue(), colour.Alpha()
94
+ print("You selected (RGBA): %d, %d, %d, %d"%(r, g, b, alpha))
95
+ print("You selected (HSVA): %d, %d, %d, %d"%(h, s, v, a))
96
+
97
+ # Once the dialog is destroyed, Mr. wx.ColourData is no longer your
98
+ # friend. Don't use it again!
99
+ dlg.Destroy()
100
+
101
+ app.MainLoop()
102
+
103
+
104
+
105
+ Window Styles
106
+ =============
107
+
108
+ This class supports the following window styles:
109
+
110
+ ================== =========== ==================================================
111
+ Window Styles Hex Value Description
112
+ ================== =========== ==================================================
113
+ ``CCD_SHOW_ALPHA`` 0x1 Show the widget used to control colour alpha channels in :class:`CubeColourDialog`.
114
+ ================== =========== ==================================================
115
+
116
+
117
+ Events Processing
118
+ =================
119
+
120
+ `No custom events are available for this class.`
121
+
122
+
123
+ License And Version
124
+ ===================
125
+
126
+ :class:`CubeColourDialog` is distributed under the wxPython license.
127
+
128
+ Latest Revision: Andrea Gavana @ 19 Dec 2012, 21.00 GMT
129
+
130
+ Version 0.5.
131
+
132
+ """
133
+
134
+
135
+ #----------------------------------------------------------------------
136
+ # Beginning Of CUBECOLOURDIALOG wxPython Code
137
+ #----------------------------------------------------------------------
138
+
139
+ import wx
140
+ import colorsys
141
+
142
+ from math import pi, sin, cos, sqrt, atan2
143
+
144
+ from wx.lib.embeddedimage import PyEmbeddedImage
145
+
146
+ # Define a translation string
147
+ _ = wx.GetTranslation
148
+
149
+ # Show the alpha control in the dialog
150
+ CCD_SHOW_ALPHA = 1
151
+ """ Show the widget used to control colour alpha channels in :class:`CubeColourDialog`. """
152
+
153
+ # Radius of the HSB colour wheel
154
+ RADIUS = 100
155
+ """ Radius of the HSB colour wheel. """
156
+
157
+ # Width of the mouse-controlled colour pointer
158
+ RECT_WIDTH = 5
159
+ """ Width of the mouse-controlled colour pointer. """
160
+
161
+ # Dictionary keys for the RGB colour cube
162
+ RED, GREEN, BLUE = 0, 1, 2
163
+ """ Dictionary keys for the RGB colour cube. """
164
+
165
+ Vertex = wx.Point(95, 109)
166
+ Top = wx.Point(95, 10)
167
+ Left = wx.Point(16, 148)
168
+ Right = wx.Point(174, 148)
169
+
170
+ colourAttributes = ["r", "g", "b", "h", "s", "v"]
171
+ colourMaxValues = [255, 255, 255, 359, 255, 255]
172
+ checkColour = wx.Colour(200, 200, 200)
173
+
174
+ HTMLCodes = {'#B0171F': ['Indian red', '2037680', ''],
175
+ '#DC143C': ['Crimson', '3937500', '#CC0033'],
176
+ '#FFB6C1': ['Lightpink', '12695295', '#FFCCCC'],
177
+ '#FFAEB9': ['Lightpink 1', '12168959', ''],
178
+ '#EEA2AD': ['Lightpink 2', '11379438', ''],
179
+ '#CD8C95': ['Lightpink 3', '9800909', ''],
180
+ '#8B5F65': ['Lightpink 4', '6643595', ''],
181
+ '#FFC0CB': ['Pink', '13353215', '#FFCCCC'],
182
+ '#FFB5C5': ['Pink 1', '12957183', ''],
183
+ '#EEA9B8': ['Pink 2', '12102126', ''],
184
+ '#CD919E': ['Pink 3', '10392013', ''],
185
+ '#8B636C': ['Pink 4', '7103371', ''],
186
+ '#DB7093': ['Palevioletred', '9662683', '#CC6699'],
187
+ '#FF82AB': ['Palevioletred 1', '11240191', ''],
188
+ '#EE799F': ['Palevioletred 2', '10451438', ''],
189
+ '#CD6889': ['Palevioletred 3', '9005261', ''],
190
+ '#8B475D': ['Palevioletred 4', '6113163', ''],
191
+ '#FFF0F5': ['Lavenderblush 1 (lavenderblush)', '16118015', '#FFFFFF'],
192
+ '#EEE0E5': ['Lavenderblush 2', '15065326', ''],
193
+ '#CDC1C5': ['Lavenderblush 3', '12960205', ''],
194
+ '#8B8386': ['Lavenderblush 4', '8815499', ''],
195
+ '#FF3E96': ['Violetred 1', '9846527', ''],
196
+ '#EE3A8C': ['Violetred 2', '9190126', ''],
197
+ '#CD3278': ['Violetred 3', '7877325', ''],
198
+ '#8B2252': ['Violetred 4', '5382795', ''],
199
+ '#FF69B4': ['Hotpink', '11823615', '#FF66CC'],
200
+ '#FF6EB4': ['Hotpink 1', '11824895', ''],
201
+ '#EE6AA7': ['Hotpink 2', '10971886', ''],
202
+ '#CD6090': ['Hotpink 3', '9461965', ''],
203
+ '#8B3A62': ['Hotpink 4', '6437515', ''],
204
+ '#872657': ['Raspberry', '5711495', ''],
205
+ '#FF1493': ['Deeppink 1 (deeppink)', '9639167', '#FF0099'],
206
+ '#EE1289': ['Deeppink 2', '8983278', ''],
207
+ '#CD1076': ['Deeppink 3', '7737549', ''],
208
+ '#8B0A50': ['Deeppink 4', '5245579', ''],
209
+ '#FF34B3': ['Maroon 1', '11744511', ''],
210
+ '#EE30A7': ['Maroon 2', '10957038', ''],
211
+ '#CD2990': ['Maroon 3', '9447885', ''],
212
+ '#8B1C62': ['Maroon 4', '6429835', ''],
213
+ '#C71585': ['Mediumvioletred', '8721863', '#CC0066'],
214
+ '#D02090': ['Violetred', '9445584', ''],
215
+ '#DA70D6': ['Orchid', '14053594', '#CC66CC'],
216
+ '#FF83FA': ['Orchid 1', '16417791', ''],
217
+ '#EE7AE9': ['Orchid 2', '15301358', ''],
218
+ '#CD69C9': ['Orchid 3', '13199821', ''],
219
+ '#8B4789': ['Orchid 4', '8996747', ''],
220
+ '#D8BFD8': ['Thistle', '14204888', '#CCCCCC'],
221
+ '#FFE1FF': ['Thistle 1', '16769535', ''],
222
+ '#EED2EE': ['Thistle 2', '15651566', ''],
223
+ '#CDB5CD': ['Thistle 3', '13481421', ''],
224
+ '#8B7B8B': ['Thistle 4', '9141131', ''],
225
+ '#FFBBFF': ['Plum 1', '16759807', ''],
226
+ '#EEAEEE': ['Plum 2', '15642350', ''],
227
+ '#CD96CD': ['Plum 3', '13473485', ''],
228
+ '#8B668B': ['Plum 4', '9135755', ''],
229
+ '#DDA0DD': ['Plum', '14524637', '#CC99CC'],
230
+ '#EE82EE': ['Violet', '15631086', '#FF99FF'],
231
+ '#FF00FF': ['Magenta (fuchsia)', '16711935', '#FF00FF'],
232
+ '#EE00EE': ['Magenta 2', '15597806', ''],
233
+ '#CD00CD': ['Magenta 3', '13435085', ''],
234
+ '#8B008B': ['Magenta 4 (darkmagenta)', '9109643', '#990099'],
235
+ '#800080': ['Purple', '8388736', '#990099'],
236
+ '#BA55D3': ['Mediumorchid', '13850042', '#CC66CC'],
237
+ '#E066FF': ['Mediumorchid 1', '16738016', ''],
238
+ '#D15FEE': ['Mediumorchid 2', '15622097', ''],
239
+ '#B452CD': ['Mediumorchid 3', '13456052', ''],
240
+ '#7A378B': ['Mediumorchid 4', '9123706', ''],
241
+ '#9400D3': ['Darkviolet', '13828244', '#9900CC'],
242
+ '#9932CC': ['Darkorchid', '13382297', '#9933CC'],
243
+ '#BF3EFF': ['Darkorchid 1', '16727743', ''],
244
+ '#B23AEE': ['Darkorchid 2', '15612594', ''],
245
+ '#9A32CD': ['Darkorchid 3', '13447834', ''],
246
+ '#68228B': ['Darkorchid 4', '9118312', ''],
247
+ '#4B0082': ['Indigo', '8519755', '#330099'],
248
+ '#8A2BE2': ['Blueviolet', '14822282', '#9933FF'],
249
+ '#9B30FF': ['Purple 1', '16724123', ''],
250
+ '#912CEE': ['Purple 2', '15608977', ''],
251
+ '#7D26CD': ['Purple 3', '13444733', ''],
252
+ '#551A8B': ['Purple 4', '9116245', ''],
253
+ '#9370DB': ['Mediumpurple', '14381203', '#9966CC'],
254
+ '#AB82FF': ['Mediumpurple 1', '16745131', ''],
255
+ '#9F79EE': ['Mediumpurple 2', '15628703', ''],
256
+ '#8968CD': ['Mediumpurple 3', '13461641', ''],
257
+ '#5D478B': ['Mediumpurple 4', '9127773', ''],
258
+ '#483D8B': ['Darkslateblue', '9125192', '#333399'],
259
+ '#8470FF': ['Lightslateblue', '16740484', ''],
260
+ '#7B68EE': ['Mediumslateblue', '15624315', '#6666FF'],
261
+ '#6A5ACD': ['Slateblue', '13458026', '#6666CC'],
262
+ '#836FFF': ['Slateblue 1', '16740227', ''],
263
+ '#7A67EE': ['Slateblue 2', '15624058', ''],
264
+ '#6959CD': ['Slateblue 3', '13457769', ''],
265
+ '#473C8B': ['Slateblue 4', '9124935', ''],
266
+ '#F8F8FF': ['Ghostwhite', '16775416', '#FFFFFF'],
267
+ '#E6E6FA': ['Lavender', '16443110', '#FFFFFF'],
268
+ '#0000FF': ['Blue', '16711680', '#0000FF'],
269
+ '#0000EE': ['Blue 2', '15597568', ''],
270
+ '#0000CD': ['Blue 3 (mediumblue)', '13434880', '#0000CC'],
271
+ '#00008B': ['Blue 4 (darkblue)', '9109504', '#000099'],
272
+ '#000080': ['Navy', '8388608', '#000099'],
273
+ '#191970': ['Midnightblue', '7346457', '#000066'],
274
+ '#3D59AB': ['Cobalt', '11229501', ''],
275
+ '#4169E1': ['Royalblue', '14772545', '#3366CC'],
276
+ '#4876FF': ['Royalblue 1', '16741960', ''],
277
+ '#436EEE': ['Royalblue 2', '15625795', ''],
278
+ '#3A5FCD': ['Royalblue 3', '13459258', ''],
279
+ '#27408B': ['Royalblue 4', '9125927', ''],
280
+ '#6495ED': ['Cornflowerblue', '15570276', '#6699FF'],
281
+ '#B0C4DE': ['Lightsteelblue', '14599344', '#99CCCC'],
282
+ '#CAE1FF': ['Lightsteelblue 1', '16769482', ''],
283
+ '#BCD2EE': ['Lightsteelblue 2', '15651516', ''],
284
+ '#A2B5CD': ['Lightsteelblue 3', '13481378', ''],
285
+ '#6E7B8B': ['Lightsteelblue 4', '9141102', ''],
286
+ '#778899': ['Lightslategray', '10061943', '#669999'],
287
+ '#708090': ['Slategray', '9470064', '#669999'],
288
+ '#C6E2FF': ['Slategray 1', '16769734', ''],
289
+ '#B9D3EE': ['Slategray 2', '15651769', ''],
290
+ '#9FB6CD': ['Slategray 3', '13481631', ''],
291
+ '#6C7B8B': ['Slategray 4', '9141100', ''],
292
+ '#1E90FF': ['Dodgerblue 1 (dodgerblue)', '16748574', '#3399FF'],
293
+ '#1C86EE': ['Dodgerblue 2', '15631900', ''],
294
+ '#1874CD': ['Dodgerblue 3', '13464600', ''],
295
+ '#104E8B': ['Dodgerblue 4', '9129488', ''],
296
+ '#F0F8FF': ['Aliceblue', '16775408', '#FFFFFF'],
297
+ '#4682B4': ['Steelblue', '11829830', '#3399CC'],
298
+ '#63B8FF': ['Steelblue 1', '16758883', ''],
299
+ '#5CACEE': ['Steelblue 2', '15641692', ''],
300
+ '#4F94CD': ['Steelblue 3', '13472847', ''],
301
+ '#36648B': ['Steelblue 4', '9135158', ''],
302
+ '#87CEFA': ['Lightskyblue', '16436871', '#99CCFF'],
303
+ '#B0E2FF': ['Lightskyblue 1', '16769712', ''],
304
+ '#A4D3EE': ['Lightskyblue 2', '15651748', ''],
305
+ '#8DB6CD': ['Lightskyblue 3', '13481613', ''],
306
+ '#607B8B': ['Lightskyblue 4', '9141088', ''],
307
+ '#87CEFF': ['Skyblue 1', '16764551', ''],
308
+ '#7EC0EE': ['Skyblue 2', '15646846', ''],
309
+ '#6CA6CD': ['Skyblue 3', '13477484', ''],
310
+ '#4A708B': ['Skyblue 4', '9138250', ''],
311
+ '#87CEEB': ['Skyblue', '15453831', '#99CCFF'],
312
+ '#00BFFF': ['Deepskyblue 1 (deepskyblue)', '16760576', '#00CCFF'],
313
+ '#00B2EE': ['Deepskyblue 2', '15643136', ''],
314
+ '#009ACD': ['Deepskyblue 3', '13474304', ''],
315
+ '#00688B': ['Deepskyblue 4', '9136128', ''],
316
+ '#33A1C9': ['Peacock', '13214003', ''],
317
+ '#ADD8E6': ['Lightblue', '15128749', '#99CCFF'],
318
+ '#BFEFFF': ['Lightblue 1', '16773055', ''],
319
+ '#B2DFEE': ['Lightblue 2', '15654834', ''],
320
+ '#9AC0CD': ['Lightblue 3', '13484186', ''],
321
+ '#68838B': ['Lightblue 4', '9143144', ''],
322
+ '#B0E0E6': ['Powderblue', '15130800', '#CCCCFF'],
323
+ '#98F5FF': ['Cadetblue 1', '16774552', ''],
324
+ '#8EE5EE': ['Cadetblue 2', '15656334', ''],
325
+ '#7AC5CD': ['Cadetblue 3', '13485434', ''],
326
+ '#53868B': ['Cadetblue 4', '9143891', ''],
327
+ '#00F5FF': ['Turquoise 1', '16774400', ''],
328
+ '#00E5EE': ['Turquoise 2', '15656192', ''],
329
+ '#00C5CD': ['Turquoise 3', '13485312', ''],
330
+ '#00868B': ['Turquoise 4', '9143808', ''],
331
+ '#5F9EA0': ['Cadetblue', '10526303', '#669999'],
332
+ '#00CED1': ['Darkturquoise', '13749760', '#00CCCC'],
333
+ '#F0FFFF': ['Azure 1 (azure)', '16777200', '#FFFFFF'],
334
+ '#E0EEEE': ['Azure 2', '15658720', ''],
335
+ '#C1CDCD': ['Azure 3', '13487553', ''],
336
+ '#838B8B': ['Azure 4', '9145219', ''],
337
+ '#E0FFFF': ['Lightcyan 1 (lightcyan)', '16777184', '#CCFFFF'],
338
+ '#D1EEEE': ['Lightcyan 2', '15658705', ''],
339
+ '#B4CDCD': ['Lightcyan 3', '13487540', ''],
340
+ '#7A8B8B': ['Lightcyan 4', '9145210', ''],
341
+ '#BBFFFF': ['Paleturquoise 1', '16777147', ''],
342
+ '#AEEEEE': ['Paleturquoise 2 (paleturquoise)', '15658670', ''],
343
+ '#96CDCD': ['Paleturquoise 3', '13487510', ''],
344
+ '#668B8B': ['Paleturquoise 4', '9145190', ''],
345
+ '#2F4F4F': ['Darkslategray', '5197615', '#336666'],
346
+ '#97FFFF': ['Darkslategray 1', '16777111', ''],
347
+ '#8DEEEE': ['Darkslategray 2', '15658637', ''],
348
+ '#79CDCD': ['Darkslategray 3', '13487481', ''],
349
+ '#528B8B': ['Darkslategray 4', '9145170', ''],
350
+ '#00FFFF': ['Cyan / aqua', '16776960', '#00FFFF'],
351
+ '#00EEEE': ['Cyan 2', '15658496', ''],
352
+ '#00CDCD': ['Cyan 3', '13487360', ''],
353
+ '#008B8B': ['Cyan 4 (darkcyan)', '9145088', '#009999'],
354
+ '#008080': ['Teal', '8421376', '#009999'],
355
+ '#48D1CC': ['Mediumturquoise', '13422920', '#33CCCC'],
356
+ '#20B2AA': ['Lightseagreen', '11186720', '#339999'],
357
+ '#03A89E': ['Manganeseblue', '10397699', ''],
358
+ '#40E0D0': ['Turquoise', '13688896', '#33CCCC'],
359
+ '#808A87': ['Coldgrey', '8882816', ''],
360
+ '#00C78C': ['Turquoiseblue', '9225984', ''],
361
+ '#7FFFD4': ['Aquamarine 1 (aquamarine)', '13959039', '#66FFCC'],
362
+ '#76EEC6': ['Aquamarine 2', '13037174', ''],
363
+ '#66CDAA': ['Aquamarine 3 (mediumaquamarine)', '11193702', '#66CC99'],
364
+ '#458B74': ['Aquamarine 4', '7637829', ''],
365
+ '#00FA9A': ['Mediumspringgreen', '10156544', '#00FF99'],
366
+ '#F5FFFA': ['Mintcream', '16449525', '#FFFFFF'],
367
+ '#00FF7F': ['Springgreen', '8388352', '#00FF66'],
368
+ '#00EE76': ['Springgreen 1', '7794176', ''],
369
+ '#00CD66': ['Springgreen 2', '6737152', ''],
370
+ '#008B45': ['Springgreen 3', '4557568', ''],
371
+ '#3CB371': ['Mediumseagreen', '7451452', '#33CC66'],
372
+ '#54FF9F': ['Seagreen 1', '10485588', ''],
373
+ '#4EEE94': ['Seagreen 2', '9760334', ''],
374
+ '#43CD80': ['Seagreen 3', '8441155', ''],
375
+ '#2E8B57': ['Seagreen 4 (seagreen)', '5737262', '#339966'],
376
+ '#00C957': ['Emeraldgreen', '5753088', ''],
377
+ '#BDFCC9': ['Mint', '13237437', ''],
378
+ '#3D9140': ['Cobaltgreen', '4231485', ''],
379
+ '#F0FFF0': ['Honeydew 1 (honeydew)', '15794160', '#FFFFFF'],
380
+ '#E0EEE0': ['Honeydew 2', '14741216', ''],
381
+ '#C1CDC1': ['Honeydew 3', '12701121', ''],
382
+ '#838B83': ['Honeydew 4', '8620931', ''],
383
+ '#8FBC8F': ['Darkseagreen', '9419919', '#99CC99'],
384
+ '#C1FFC1': ['Darkseagreen 1', '12713921', ''],
385
+ '#B4EEB4': ['Darkseagreen 2', '11857588', ''],
386
+ '#9BCD9B': ['Darkseagreen 3', '10210715', ''],
387
+ '#698B69': ['Darkseagreen 4', '6916969', ''],
388
+ '#98FB98': ['Palegreen', '10025880', '#99FF99'],
389
+ '#9AFF9A': ['Palegreen 1', '10157978', ''],
390
+ '#90EE90': ['Palegreen 2 (lightgreen)', '9498256', '#99FF99'],
391
+ '#7CCD7C': ['Palegreen 3', '8179068', ''],
392
+ '#548B54': ['Palegreen 4', '5540692', ''],
393
+ '#32CD32': ['Limegreen', '3329330', '#33CC33'],
394
+ '#228B22': ['Forestgreen', '2263842', '#339933'],
395
+ '#00FF00': ['Green 1 (lime)', '65280', '#00FF00'],
396
+ '#00EE00': ['Green 2', '60928', ''],
397
+ '#00CD00': ['Green 3', '52480', ''],
398
+ '#008B00': ['Green 4', '35584', ''],
399
+ '#008000': ['Green', '32768', '#009900'],
400
+ '#006400': ['Darkgreen', '25600', '#006600'],
401
+ '#308014': ['Sapgreen', '1343536', ''],
402
+ '#7CFC00': ['Lawngreen', '64636', '#66FF00'],
403
+ '#7FFF00': ['Chartreuse 1 (chartreuse)', '65407', '#66FF00'],
404
+ '#76EE00': ['Chartreuse 2', '61046', ''],
405
+ '#66CD00': ['Chartreuse 3', '52582', ''],
406
+ '#458B00': ['Chartreuse 4', '35653', ''],
407
+ '#ADFF2F': ['Greenyellow', '3145645', '#99FF33'],
408
+ '#CAFF70': ['Darkolivegreen 1', '7405514', ''],
409
+ '#BCEE68': ['Darkolivegreen 2', '6876860', ''],
410
+ '#A2CD5A': ['Darkolivegreen 3', '5950882', ''],
411
+ '#6E8B3D': ['Darkolivegreen 4', '4033390', ''],
412
+ '#556B2F': ['Darkolivegreen', '3107669', '#666633'],
413
+ '#6B8E23': ['Olivedrab', '2330219', '#669933'],
414
+ '#C0FF3E': ['Olivedrab 1', '4128704', ''],
415
+ '#B3EE3A': ['Olivedrab 2', '3862195', ''],
416
+ '#9ACD32': ['Olivedrab 3 (yellowgreen)', '3329434', '#99CC33'],
417
+ '#698B22': ['Olivedrab 4', '2263913', ''],
418
+ '#FFFFF0': ['Ivory 1 (ivory)', '15794175', '#FFFFFF'],
419
+ '#EEEEE0': ['Ivory 2', '14741230', ''],
420
+ '#CDCDC1': ['Ivory 3', '12701133', ''],
421
+ '#8B8B83': ['Ivory 4', '8620939', ''],
422
+ '#F5F5DC': ['Beige', '14480885', '#FFFFCC'],
423
+ '#FFFFE0': ['Lightyellow 1 (lightyellow)', '14745599', '#FFFFFF'],
424
+ '#EEEED1': ['Lightyellow 2', '13758190', ''],
425
+ '#CDCDB4': ['Lightyellow 3', '11849165', ''],
426
+ '#8B8B7A': ['Lightyellow 4', '8031115', ''],
427
+ '#FAFAD2': ['Lightgoldenrodyellow', '13826810', '#FFFFCC'],
428
+ '#FFFF00': ['Yellow 1 (yellow)', '65535', '#FFFF00'],
429
+ '#EEEE00': ['Yellow 2', '61166', ''],
430
+ '#CDCD00': ['Yellow 3', '52685', ''],
431
+ '#8B8B00': ['Yellow 4', '35723', ''],
432
+ '#808069': ['Warmgrey', '6914176', ''],
433
+ '#808000': ['Olive', '32896', '#999900'],
434
+ '#BDB76B': ['Darkkhaki', '7059389', '#CCCC66'],
435
+ '#FFF68F': ['Khaki 1', '9434879', ''],
436
+ '#EEE685': ['Khaki 2', '8775406', ''],
437
+ '#CDC673': ['Khaki 3', '7587533', ''],
438
+ '#8B864E': ['Khaki 4', '5146251', ''],
439
+ '#F0E68C': ['Khaki', '9234160', ''],
440
+ '#EEE8AA': ['Palegoldenrod', '11200750', '#FFFF99'],
441
+ '#FFFACD': ['Lemonchiffon 1 (lemonchiffon)', '13499135', '#FFFFCC'],
442
+ '#EEE9BF': ['Lemonchiffon 2', '12577262', ''],
443
+ '#CDC9A5': ['Lemonchiffon 3', '10865101', ''],
444
+ '#8B8970': ['Lemonchiffon 4', '7375243', ''],
445
+ '#FFEC8B': ['Lightgoldenrod 1', '9170175', ''],
446
+ '#EEDC82': ['Lightgoldenrod 2', '8576238', ''],
447
+ '#CDBE70': ['Lightgoldenrod 3', '7388877', ''],
448
+ '#8B814C': ['Lightgoldenrod 4', '5013899', ''],
449
+ '#E3CF57': ['Banana', '5754851', ''],
450
+ '#FFD700': ['Gold 1 (gold)', '55295', '#FFCC00'],
451
+ '#EEC900': ['Gold 2', '51694', ''],
452
+ '#CDAD00': ['Gold 3', '44493', ''],
453
+ '#8B7500': ['Gold 4', '30091', ''],
454
+ '#FFF8DC': ['Cornsilk 1 (cornsilk)', '14481663', '#FFFFCC'],
455
+ '#EEE8CD': ['Cornsilk 2', '13494510', ''],
456
+ '#CDC8B1': ['Cornsilk 3', '11651277', ''],
457
+ '#8B8878': ['Cornsilk 4', '7899275', ''],
458
+ '#DAA520': ['Goldenrod', '2139610', '#CC9933'],
459
+ '#FFC125': ['Goldenrod 1', '2474495', ''],
460
+ '#EEB422': ['Goldenrod 2', '2274542', ''],
461
+ '#CD9B1D': ['Goldenrod 3', '1940429', ''],
462
+ '#8B6914': ['Goldenrod 4', '1337739', ''],
463
+ '#B8860B': ['Darkgoldenrod', '755384', '#CC9900'],
464
+ '#FFB90F': ['Darkgoldenrod 1', '1030655', ''],
465
+ '#EEAD0E': ['Darkgoldenrod 2', '962030', ''],
466
+ '#CD950C': ['Darkgoldenrod 3', '824781', ''],
467
+ '#8B6508': ['Darkgoldenrod 4', '550283', ''],
468
+ '#FFA500': ['Orange 1 (orange)', '42495', '#FF9900'],
469
+ '#EE9A00': ['Orange 2', '39662', ''],
470
+ '#CD8500': ['Orange 3', '34253', ''],
471
+ '#8B5A00': ['Orange 4', '23179', ''],
472
+ '#FFFAF0': ['Floralwhite', '15792895', '#FFFFFF'],
473
+ '#FDF5E6': ['Oldlace', '15136253', '#FFFFFF'],
474
+ '#F5DEB3': ['Wheat', '11788021', '#FFCCCC'],
475
+ '#FFE7BA': ['Wheat 1', '12249087', ''],
476
+ '#EED8AE': ['Wheat 2', '11458798', ''],
477
+ '#CDBA96': ['Wheat 3', '9878221', ''],
478
+ '#8B7E66': ['Wheat 4', '6717067', ''],
479
+ '#FFE4B5': ['Moccasin', '11920639', '#FFCCCC'],
480
+ '#FFEFD5': ['Papayawhip', '14020607', '#FFFFCC'],
481
+ '#FFEBCD': ['Blanchedalmond', '13495295', '#FFFFCC'],
482
+ '#FFDEAD': ['Navajowhite 1 (navajowhite)', '11394815', '#FFCC99'],
483
+ '#EECFA1': ['Navajowhite 2', '10604526', ''],
484
+ '#CDB38B': ['Navajowhite 3', '9155533', ''],
485
+ '#8B795E': ['Navajowhite 4', '6191499', ''],
486
+ '#FCE6C9': ['Eggshell', '13231868', ''],
487
+ '#D2B48C': ['Tan', '9221330', '#CCCC99'],
488
+ '#9C661F': ['Brick', '2057884', ''],
489
+ '#FF9912': ['Cadmiumyellow', '1219071', ''],
490
+ '#FAEBD7': ['Antiquewhite', '14150650', '#FFFFCC'],
491
+ '#FFEFDB': ['Antiquewhite 1', '14413823', ''],
492
+ '#EEDFCC': ['Antiquewhite 2', '13426670', ''],
493
+ '#CDC0B0': ['Antiquewhite 3', '11583693', ''],
494
+ '#8B8378': ['Antiquewhite 4', '7897995', ''],
495
+ '#DEB887': ['Burlywood', '8894686', '#CCCC99'],
496
+ '#FFD39B': ['Burlywood 1', '10212351', ''],
497
+ '#EEC591': ['Burlywood 2', '9553390', ''],
498
+ '#CDAA7D': ['Burlywood 3', '8235725', ''],
499
+ '#8B7355': ['Burlywood 4', '5600139', ''],
500
+ '#FFE4C4': ['Bisque 1 (bisque)', '12903679', '#FFFFCC'],
501
+ '#EED5B7': ['Bisque 2', '12047854', ''],
502
+ '#CDB79E': ['Bisque 3', '10401741', ''],
503
+ '#8B7D6B': ['Bisque 4', '7044491', ''],
504
+ '#E3A869': ['Melon', '6924515', ''],
505
+ '#ED9121': ['Carrot', '2200045', ''],
506
+ '#FF8C00': ['Darkorange', '36095', '#FF9900'],
507
+ '#FF7F00': ['Darkorange 1', '32767', ''],
508
+ '#EE7600': ['Darkorange 2', '30446', ''],
509
+ '#CD6600': ['Darkorange 3', '26317', ''],
510
+ '#8B4500': ['Darkorange 4', '17803', ''],
511
+ '#FF8000': ['Orange', '33023', ''],
512
+ '#FFA54F': ['Tan 1', '5219839', ''],
513
+ '#EE9A49': ['Tan 2', '4823790', ''],
514
+ '#CD853F': ['Tan 3 (peru)', '4163021', '#CC9933'],
515
+ '#8B5A2B': ['Tan 4', '2841227', ''],
516
+ '#FAF0E6': ['Linen', '15134970', '#FFFFFF'],
517
+ '#FFDAB9': ['Peachpuff 1 (peachpuff)', '12180223', '#FFCCCC'],
518
+ '#EECBAD': ['Peachpuff 2', '11389934', ''],
519
+ '#CDAF95': ['Peachpuff 3', '9809869', ''],
520
+ '#8B7765': ['Peachpuff 4', '6649739', ''],
521
+ '#FFF5EE': ['Seashell 1 (seashell)', '15660543', '#FFFFFF'],
522
+ '#EEE5DE': ['Seashell 2', '14607854', ''],
523
+ '#CDC5BF': ['Seashell 3', '12568013', ''],
524
+ '#8B8682': ['Seashell 4', '8554123', ''],
525
+ '#F4A460': ['Sandybrown', '6333684', '#FF9966'],
526
+ '#C76114': ['Rawsienna', '1335751', ''],
527
+ '#D2691E': ['Chocolate', '1993170', '#CC6633'],
528
+ '#FF7F24': ['Chocolate 1', '2392063', ''],
529
+ '#EE7621': ['Chocolate 2', '2193134', ''],
530
+ '#CD661D': ['Chocolate 3', '1926861', ''],
531
+ '#8B4513': ['Chocolate 4 (saddlebrown)', '1262987', '#993300'],
532
+ '#292421': ['Ivoryblack', '2171945', ''],
533
+ '#FF7D40': ['Flesh', '4226559', ''],
534
+ '#FF6103': ['Cadmiumorange', '221695', ''],
535
+ '#8A360F': ['Burntsienna', '997002', ''],
536
+ '#A0522D': ['Sienna', '2970272', '#996633'],
537
+ '#FF8247': ['Sienna 1', '4686591', ''],
538
+ '#EE7942': ['Sienna 2', '4356590', ''],
539
+ '#CD6839': ['Sienna 3', '3762381', ''],
540
+ '#8B4726': ['Sienna 4', '2508683', ''],
541
+ '#FFA07A': ['Lightsalmon 1 (lightsalmon)', '8036607', '#FF9966'],
542
+ '#EE9572': ['Lightsalmon 2', '7509486', ''],
543
+ '#CD8162': ['Lightsalmon 3', '6455757', ''],
544
+ '#8B5742': ['Lightsalmon 4', '4347787', ''],
545
+ '#FF7F50': ['Coral', '5275647', '#FF6666'],
546
+ '#FF4500': ['Orangered 1 (orangered)', '17919', '#FF3300'],
547
+ '#EE4000': ['Orangered 2', '16622', ''],
548
+ '#CD3700': ['Orangered 3', '14285', ''],
549
+ '#8B2500': ['Orangered 4', '9611', ''],
550
+ '#5E2612': ['Sepia', '1189470', ''],
551
+ '#E9967A': ['Darksalmon', '8034025', '#FF9966'],
552
+ '#FF8C69': ['Salmon 1', '6917375', ''],
553
+ '#EE8262': ['Salmon 2', '6456046', ''],
554
+ '#CD7054': ['Salmon 3', '5533901', ''],
555
+ '#8B4C39': ['Salmon 4', '3755147', ''],
556
+ '#FF7256': ['Coral 1', '5665535', ''],
557
+ '#EE6A50': ['Coral 2', '5270254', ''],
558
+ '#CD5B45': ['Coral 3', '4545485', ''],
559
+ '#8B3E2F': ['Coral 4', '3096203', ''],
560
+ '#8A3324': ['Burntumber', '2372490', ''],
561
+ '#FF6347': ['Tomato 1 (tomato)', '4678655', '#FF6633'],
562
+ '#EE5C42': ['Tomato 2', '4349166', ''],
563
+ '#CD4F39': ['Tomato 3', '3755981', ''],
564
+ '#8B3626': ['Tomato 4', '2504331', ''],
565
+ '#FA8072': ['Salmon', '7504122', '#FF9966'],
566
+ '#FFE4E1': ['Mistyrose 1 (mistyrose)', '14804223', '#FFCCFF'],
567
+ '#EED5D2': ['Mistyrose 2', '13817326', ''],
568
+ '#CDB7B5': ['Mistyrose 3', '11909069', ''],
569
+ '#8B7D7B': ['Mistyrose 4', '8093067', ''],
570
+ '#FFFAFA': ['Snow 1 (snow)', '16448255', '#FFFFFF'],
571
+ '#EEE9E9': ['Snow 2', '15329774', ''],
572
+ '#CDC9C9': ['Snow 3', '13224397', ''],
573
+ '#8B8989': ['Snow 4', '9013643', ''],
574
+ '#BC8F8F': ['Rosybrown', '9408444', '#CC9999'],
575
+ '#FFC1C1': ['Rosybrown 1', '12698111', ''],
576
+ '#EEB4B4': ['Rosybrown 2', '11842798', ''],
577
+ '#CD9B9B': ['Rosybrown 3', '10197965', ''],
578
+ '#8B6969': ['Rosybrown 4', '6908299', ''],
579
+ '#F08080': ['Lightcoral', '8421616', '#FF9999'],
580
+ '#CD5C5C': ['Indianred', '6053069', '#CC6666'],
581
+ '#FF6A6A': ['Indianred 1', '6974207', ''],
582
+ '#EE6363': ['Indianred 2', '6513646', ''],
583
+ '#8B3A3A': ['Indianred 4', '3816075', ''],
584
+ '#CD5555': ['Indianred 3', '5592525', ''],
585
+ '#A52A2A': ['Brown', '2763429', '#993333'],
586
+ '#FF4040': ['Brown 1', '4210943', ''],
587
+ '#EE3B3B': ['Brown 2', '3881966', ''],
588
+ '#CD3333': ['Brown 3', '3355597', ''],
589
+ '#8B2323': ['Brown 4', '2302859', ''],
590
+ '#B22222': ['Firebrick', '2237106', '#993333'],
591
+ '#FF3030': ['Firebrick 1', '3158271', ''],
592
+ '#EE2C2C': ['Firebrick 2', '2895086', ''],
593
+ '#CD2626': ['Firebrick 3', '2500301', ''],
594
+ '#8B1A1A': ['Firebrick 4', '1710731', ''],
595
+ '#FF0000': ['Red 1 (red)', '255', '#FF0000'],
596
+ '#EE0000': ['Red 2', '238', ''],
597
+ '#CD0000': ['Red 3', '205', ''],
598
+ '#8B0000': ['Red 4 (darkred)', '139', '#990000'],
599
+ '#800000': ['Maroon', '128', '#990000'],
600
+ '#8E388E': ['Sgi beet', '9320590', ''],
601
+ '#7171C6': ['Sgi slateblue', '13005169', ''],
602
+ '#7D9EC0': ['Sgi lightblue', '12623485', ''],
603
+ '#388E8E': ['Sgi teal', '9342520', ''],
604
+ '#71C671': ['Sgi chartreuse', '7456369', ''],
605
+ '#8E8E38': ['Sgi olivedrab', '3706510', ''],
606
+ '#C5C1AA': ['Sgi brightgray', '11190725', ''],
607
+ '#C67171': ['Sgi salmon', '7434694', ''],
608
+ '#555555': ['Sgi darkgray', '5592405', ''],
609
+ '#1E1E1E': ['Sgi gray 12', '1973790', ''],
610
+ '#282828': ['Sgi gray 16', '2631720', ''],
611
+ '#515151': ['Sgi gray 32', '5329233', ''],
612
+ '#5B5B5B': ['Sgi gray 36', '5987163', ''],
613
+ '#848484': ['Sgi gray 52', '8684676', ''],
614
+ '#8E8E8E': ['Sgi gray 56', '9342606', ''],
615
+ '#AAAAAA': ['Sgi lightgray', '11184810', ''],
616
+ '#B7B7B7': ['Sgi gray 72', '12040119', ''],
617
+ '#C1C1C1': ['Sgi gray 76', '12698049', ''],
618
+ '#EAEAEA': ['Sgi gray 92', '15395562', ''],
619
+ '#F4F4F4': ['Sgi gray 96', '16053492', ''],
620
+ '#FFFFFF': ['White', '16777215', '#FFFFFF'],
621
+ '#F5F5F5': ['White smoke (gray)', '16119285', '#FFFFFF'],
622
+ '#DCDCDC': ['Gainsboro', '14474460', '#CCCCCC'],
623
+ '#D3D3D3': ['Lightgrey', '13882323', '#CCCCCC'],
624
+ '#C0C0C0': ['Silver', '12632256', '#CCCCCC'],
625
+ '#A9A9A9': ['Darkgray', '11119017', '#999999'],
626
+ '#808080': ['Gray', '8421504', ''],
627
+ '#696969': ['Dimgray (gray 42)', '6908265', '#666666'],
628
+ '#000000': ['Black', '0', '#000000'],
629
+ '#FCFCFC': ['Gray 99', '16579836', ''],
630
+ '#FAFAFA': ['Gray 98', '16448250', ''],
631
+ '#F7F7F7': ['Gray 97', '16250871', ''],
632
+ '#F2F2F2': ['Gray 95', '15921906', ''],
633
+ '#F0F0F0': ['Gray 94', '15790320', ''],
634
+ '#EDEDED': ['Gray 93', '15592941', ''],
635
+ '#EBEBEB': ['Gray 92', '15461355', ''],
636
+ '#E8E8E8': ['Gray 91', '15263976', ''],
637
+ '#E5E5E5': ['Gray 90', '15066597', ''],
638
+ '#E3E3E3': ['Gray 89', '14935011', ''],
639
+ '#E0E0E0': ['Gray 88', '14737632', ''],
640
+ '#DEDEDE': ['Gray 87', '14606046', ''],
641
+ '#DBDBDB': ['Gray 86', '14408667', ''],
642
+ '#D9D9D9': ['Gray 85', '14277081', ''],
643
+ '#D6D6D6': ['Gray 84', '14079702', ''],
644
+ '#D4D4D4': ['Gray 83', '13948116', ''],
645
+ '#D1D1D1': ['Gray 82', '13750737', ''],
646
+ '#CFCFCF': ['Gray 81', '13619151', ''],
647
+ '#CCCCCC': ['Gray 80', '13421772', ''],
648
+ '#C9C9C9': ['Gray 79', '13224393', ''],
649
+ '#C7C7C7': ['Gray 78', '13092807', ''],
650
+ '#C4C4C4': ['Gray 77', '12895428', ''],
651
+ '#C2C2C2': ['Gray 76', '12763842', ''],
652
+ '#BFBFBF': ['Gray 75', '12566463', ''],
653
+ '#BDBDBD': ['Gray 74', '12434877', ''],
654
+ '#BABABA': ['Gray 73', '12237498', ''],
655
+ '#B8B8B8': ['Gray 72', '12105912', ''],
656
+ '#B5B5B5': ['Gray 71', '11908533', ''],
657
+ '#B3B3B3': ['Gray 70', '11776947', ''],
658
+ '#B0B0B0': ['Gray 69', '11579568', ''],
659
+ '#ADADAD': ['Gray 68', '11382189', ''],
660
+ '#ABABAB': ['Gray 67', '11250603', ''],
661
+ '#A8A8A8': ['Gray 66', '11053224', ''],
662
+ '#A6A6A6': ['Gray 65', '10921638', ''],
663
+ '#A3A3A3': ['Gray 64', '10724259', ''],
664
+ '#A1A1A1': ['Gray 63', '10592673', ''],
665
+ '#9E9E9E': ['Gray 62', '10395294', ''],
666
+ '#9C9C9C': ['Gray 61', '10263708', ''],
667
+ '#999999': ['Gray 60', '10066329', ''],
668
+ '#969696': ['Gray 59', '9868950', ''],
669
+ '#949494': ['Gray 58', '9737364', ''],
670
+ '#919191': ['Gray 57', '9539985', ''],
671
+ '#8F8F8F': ['Gray 56', '9408399', ''],
672
+ '#8C8C8C': ['Gray 55', '9211020', ''],
673
+ '#8A8A8A': ['Gray 54', '9079434', ''],
674
+ '#878787': ['Gray 53', '8882055', ''],
675
+ '#858585': ['Gray 52', '8750469', ''],
676
+ '#828282': ['Gray 51', '8553090', ''],
677
+ '#7F7F7F': ['Gray 50', '8355711', ''],
678
+ '#7D7D7D': ['Gray 49', '8224125', ''],
679
+ '#7A7A7A': ['Gray 48', '8026746', ''],
680
+ '#787878': ['Gray 47', '7895160', ''],
681
+ '#757575': ['Gray 46', '7697781', ''],
682
+ '#737373': ['Gray 45', '7566195', ''],
683
+ '#707070': ['Gray 44', '7368816', ''],
684
+ '#6E6E6E': ['Gray 43', '7237230', ''],
685
+ '#6B6B6B': ['Gray 42', '7039851', ''],
686
+ '#696969': ['Dimgray (gray 42)', '6908265', '#666666'],
687
+ '#666666': ['Gray 40', '6710886', ''],
688
+ '#636363': ['Gray 39', '6513507', ''],
689
+ '#616161': ['Gray 38', '6381921', ''],
690
+ '#5E5E5E': ['Gray 37', '6184542', ''],
691
+ '#5C5C5C': ['Gray 36', '6052956', ''],
692
+ '#595959': ['Gray 35', '5855577', ''],
693
+ '#575757': ['Gray 34', '5723991', ''],
694
+ '#545454': ['Gray 33', '5526612', ''],
695
+ '#525252': ['Gray 32', '5395026', ''],
696
+ '#4F4F4F': ['Gray 31', '5197647', ''],
697
+ '#4D4D4D': ['Gray 30', '5066061', ''],
698
+ '#4A4A4A': ['Gray 29', '4868682', ''],
699
+ '#474747': ['Gray 28', '4671303', ''],
700
+ '#454545': ['Gray 27', '4539717', ''],
701
+ '#424242': ['Gray 26', '4342338', ''],
702
+ '#404040': ['Gray 25', '4210752', ''],
703
+ '#3D3D3D': ['Gray 24', '4013373', ''],
704
+ '#3B3B3B': ['Gray 23', '3881787', ''],
705
+ '#383838': ['Gray 22', '3684408', ''],
706
+ '#363636': ['Gray 21', '3552822', ''],
707
+ '#333333': ['Gray 20', '3355443', ''],
708
+ '#303030': ['Gray 19', '3158064', ''],
709
+ '#2E2E2E': ['Gray 18', '3026478', ''],
710
+ '#2B2B2B': ['Gray 17', '2829099', ''],
711
+ '#292929': ['Gray 16', '2697513', ''],
712
+ '#262626': ['Gray 15', '2500134', ''],
713
+ '#242424': ['Gray 14', '2368548', ''],
714
+ '#212121': ['Gray 13', '2171169', ''],
715
+ '#1F1F1F': ['Gray 12', '2039583', ''],
716
+ '#1C1C1C': ['Gray 11', '1842204', ''],
717
+ '#1A1A1A': ['Gray 10', '1710618', ''],
718
+ '#171717': ['Gray 9', '1513239', ''],
719
+ '#141414': ['Gray 8', '1315860', ''],
720
+ '#121212': ['Gray 7', '1184274', ''],
721
+ '#0F0F0F': ['Gray 6', '986895', ''],
722
+ '#0D0D0D': ['Gray 5', '855309', ''],
723
+ '#0A0A0A': ['Gray 4', '657930', ''],
724
+ '#080808': ['Gray 3', '526344', ''],
725
+ '#050505': ['Gray 2', '328965', ''],
726
+ '#030303': ['Gray 1', '197379', ''],
727
+ }
728
+
729
+
730
+ HSVWheelImage = PyEmbeddedImage(
731
+ "iVBORw0KGgoAAAANSUhEUgAAAMoAAADJCAIAAADtkzpRAAAAA3NCSVQICAjb4U/gAAAgAElE"
732
+ "QVR4nO2decgsz3fWn6q5MWLcgsaoqAiKRBM14gJuNCj0T9SIuEVRiEIwSDSCElFJBPegKGqI"
733
+ "a1QigiYuqFHQEeU3RtSgRjQ/0ASXgBqXuGBihPh7u45/VJ1znnOqet737vd+vzZz5/b09PQs"
734
+ "/ennPPVUdb/lox/9KP7/NE1/ddsrUIELwDPLhz/qdn3bn/cdnZ697Q/wNqcv3/YSWCkVYg+B"
735
+ "Akhfs9zdzse2/YzC7/fhJu/DhdcfIJ4uKBWlQApQUAtQgIJyQa2QAikoFejrF5qpNKPLRV/e"
736
+ "bx1KKcB/3XZm7rt+yGj74OP1O+MOrkQSEVONGABAqQMjQw3pVlczypkogvZCKQAg/4c/zIcA"
737
+ "tQ8mXl+07cUlysWps6U7/lJdbAroWSMGSmGZFCuyFTBK8xFQ0XsBofYdH1DUPlB4fWHwUh2p"
738
+ "XgGdrV4K6yQ/3WwV4mmpVcuHzBlp2HhISJnCSULtuyhq/+uDxdkHAa8v2HYMrapa1IrVO8SC"
739
+ "aPMYDzscJULDy2Wug5OeSYJskjShNZk2CXoG+WRtJfzXDwRn7zdenzcO+nJBKa49Nm8qVVS9"
740
+ "2G+xShUlrJj8KCt9axmyOnGWwJpkbKYtsGVSB0iBfL9tvwD/4T2H7L3E61eQXFE5qxGvoVDk"
741
+ "t4wnLoKdp6KK1TDm+wsby9iZA5u9fPL1NepZHUsWbPFTQPtBKmb/5v3k7D3D65cOz97lyg3W"
742
+ "dDPpKlC/VRQROFgueBXA8PulogINQMWFKHnUk61FS99FCKzCYJGS+ZIyVhti9sO2/QL8y/cN"
743
+ "svcGr1+odbAGfeoy47e5RCaGdE2k0AuQilrHHkXFpasXF9NYNOeayA/npuLa1BfHsUUxk1nM"
744
+ "Pn3bL8C/eH8gew/w+rnaP6MKFG59JxZNrBSRZMKG/CAs7I7KoGy6/VZRFbJnBU1V5FTAuNn4"
745
+ "mPcKNbEGti4EFrQuG3NjBaB95rZfgH/6PkD2TuP1szS+wgSWOqpagysflisVyhpnVLeKalXR"
746
+ "GKybrWcF0msrRn1c+K1owpK1ytlEnUQrJhSt4KLS2FTPSvH7PAO0n7DtF+AfvtuQvaN47dsO"
747
+ "4JkSoykDsxWqJLkrhsmNv+UU+vBiu0pTDClOZyWGvNlYI2RpPvn38yqZwrAOetawdKs0o35O"
748
+ "gPaTt/0C/L13FbL6+CpvfNq3nwnUilr8Vgou/VbxrISn+u1CM12HLiXf14JL9flaUCs+wdaB"
749
+ "vkv1V10KatW3ps+QHvJbX+ztani7S0WtY2v8kWz7NX02XTiW18VvMpzA9lP3t73T1tO7pV77"
750
+ "9nMwpKVC7Y7mVW62pgyiFpccbzYWFz9vKvbmoYqc0Ba6KoyaeHHjHwRsKovB4MdsIgRdNeuZ"
751
+ "mffQhGSDX9FUZU3Vmq7jVRIQQLaftKPh9o/eLRl7V/Dat58PoAzfw7EQusTa8VqASFiNuZf3"
752
+ "/Bhn9HKptNocpery7utr9bJ152bNSV/znC2HCQu2rFAK2a95BloiW0VFA1qDCKRtP37HgdvX"
753
+ "vSuQvRN47dtnY3QwLw9os1k1YpSNF2kVNx5BAuZUEYh93lSnGh9wrxa817KbiIdLMEyRvGZa"
754
+ "GK29ffd0dLXkwLrxwlCy0qmCVIhACqQBsv3o/fbP3wnC3j5e+/ZLVflhyXVsohsoNeZbhXDp"
755
+ "hc/vuXrGyL6S6+fuSFgfpb324t1KbdatabhEkqi5A7u3T/n4AbUw/Itzi9JqYkUrmrLWEaMI"
756
+ "RCCAiN4wZOwz9tvH3j5hbxOvffscaCOOG1NxB/QffSgWAljcYGQZQySsL0kRvzGUZkL3UZ8i"
757
+ "lC0JGHNWc1lEiSTN6Vd1sFizuUUplAAPyIbxkjZEqzU0QWuQijZkbPvhOw7cvvFtQvbW8Nq3"
758
+ "zyWnFX76pGEFwCCsQxPMFht/NvIIUT6rFEsaqFb6vMX6FaWqbqUY7MRmGW3By9OSJGbLh4tI"
759
+ "gqyYrWw1UYACaYMzljG07Yfut3/91gh7O3jt2+dp4y7gpYep/bLdZduu6h6/wCELYFGzcR2x"
760
+ "1iBOVUcomLvySgr3XhdiJcgVx2Ap96KvVsqKrQrUIYSJJ3SBrKMCZvulkDW0ApGgW2a/3I0B"
761
+ "TbYfvN++6e0Q9qbx2rfPRyyI6cieHiaPXzGk6H7LMekZyLE5ScUlyrsUi4pWRblot2MsgukW"
762
+ "4JvHpnLho29nvgoUN3TmLojtxAmyVlAhgmZmq6jHF7VnHbthy7YfuOPA7ZvfNGRvFK99+7Xw"
763
+ "3o9gfvngnrwX1PEUKGEUKt65mVANwWOJ6u0v3VSXutbDiJ6N9c9c8ayiUbCeG48TZ6lWSuRs"
764
+ "yVb3+8UqYPT4nrpVtNFybAyTUPtR7dcAC/4U2vap++2/vFHC3hxe+/bry0q0av7p54dCVqlY"
765
+ "0FoHNJxZLAnz1iW1IosNkbAt0zqiLv6iKJwKWDxOWLQWSqZCZfGV9TaG4mhyZcYfzrdMYUR/"
766
+ "CLf5XiURsJO2fe/99t/eHGFvCK99+w32O841MaIWCoq+5KK1w6GBO30wYamFWL16mhsbq1Hf"
767
+ "diWfVIoOl9Amxbo/e1q+8F7ktJJoDbdOvY0uZvaSHsrryjpowmEi1BrQuFy2geUolC5m2yfv"
768
+ "t//5hgh7E3jt22/up+VEmBZ+i/jzp5S5WnzGyhnbdnf0dl8BOJFppiivtnGup50SHk54lqmy"
769
+ "95qzCW7rJbb4KWvTFBpyaBUzhRF1iFYXqg7WkCshxRrWfkDWmqdi332/feubIOy147VvX0xj"
770
+ "3sdBOctYfGitKnsqeRGjJ6DGtBUALmkWTNj5jJU2BSWpf4AaEekGn8vc2Y1zYK/yKeuqC7aG"
771
+ "blUSnHiDKZwSo0KVwSJr38kD+zCbadsn7bdvf+2EvV689u23UiNxeHZOuWqEjFDz2IIFjwhb"
772
+ "jABTrRpmizTM8zCyXyABM0Gyl7tWwV+VpYvzCBp4PXsvifxlerj3WstodvcFgAhaGa1Codxr"
773
+ "VqwG4o/xamijkm6fuN++4/US9hrx2rffUcfYhGY/t3GmS1oUrcRTWshHc4ETVnXX+kzJ914u"
774
+ "CSzudkQfYq9G3kIyHw89e69Zq2YfdiJjpljD4EeSRrilLkIqWhmJ/HkY0TSMACPFLcru5XzJ"
775
+ "9mzHgZu8LsheC1779iUYfnyETFQTTRi6klkQxd6r6C/r9ZSPZjXFxbQKFFJMwwxDuxKOGqDG"
776
+ "33C5aIksgK7ZXaN3B02Q2Sf0b0EJRWiyRMWyGLnwt2PRYuNFMNl8h6YLEiG1Viwz+1Nz8thv"
777
+ "l9dC2GtSLwu3kpsx72W/uw1PSNbehix7GY14AdRHFJFahhQsYF4l4YUStKYUX6eUcdYQD2Fd"
778
+ "GHy6P6uPrs1PCSPo2RRGyPBVLmMnYUSrOiSMlQwQDCgtEvu/++07vXrCXj1e+/b7Uyif7HzN"
779
+ "cjXfz63IFveWiZzfVMlGbDGd0LFuP5KCdjlsZvu06dAqPsGy+5WAcQVMhVKIV4nLGTsLI7wm"
780
+ "khmwBqOKVjdevag2NvWsTzLqYCfMlKxplTRVU8JeOQl45Xjt2x/koKgueAqcxZkZL08lJncP"
781
+ "OrenEE+euJ4M/2I7z0+J1VkNBSrQKp5hnDt0Fnd5WYzqlewXZxYtMmdhhEcS7O4nF2/OnYug"
782
+ "BHosj/CQDEoYzZPObf9nv32XVyxgrxKvffuylG9xdbCHE1U5D2Plm70XYefjCjFm7OEcgM08"
783
+ "gQLYsMTCsN5QmEdJ3PFe0weG1jtDzbRqroPBeBlkaGX0W3tvT3FTH5xW17OZKlFfH1ELGla2"
784
+ "b9tv3+1VEvbK8Nq3P8pj5eoJT2dVkvHih7S3Go+nSCHF1PlYAaQwbB5jCBczQ00uI8EHRpFN"
785
+ "hS97LzZbVM1nsEzGiq6WNCyFEeMlqlKUO5iMNfZYsvJYMrzXwtebmPGStv3P/fbJr4ywV4PX"
786
+ "vv0JeCOfdct2SeIpiZatYKaqRchCIyBKHdJQaR7RWkfcgBSGmbUn5vrHuERcSskYZQGj3Iut"
787
+ "2Lo+EnDzOWcmV9Cuaynmt7J/l9Edb1qVW4sUfc1UtYZW0Io6M2tdCkS2b9lvn/JqCHsFeO3b"
788
+ "n8KoiQ7W7L1mGSM+OLYYMKlisXgkMRh7C45XmW6I2oZJybhiQuts1qc6cCx1FYNFhuwYC/GE"
789
+ "fdkIk6Tv0nuBoKsthtKvx0Sk+6nxKMuyqO3HNmnYf95v3/cVEPayeO3bV1gMoT9rmaCxheua"
790
+ "SGyxtpmj9w6iyeCbZrivT1WSC6IhBWfOJK1/jEKfLY0D6ze7piEY/fveK1pGbpr0bzdzZq1F"
791
+ "lqsuSNRa9B6hyFOLhInFEy0q1qpW6sLtP+y3H/CyhL28el1mTeKfft4NBJ+YwvFeiUomego1"
792
+ "athbYVchMMSnEiGd/3ju9MVCV4OsoABSRo9TOJvjzHstNaxmmwUe5lUgddUX5DZrjIZI9msK"
793
+ "IzjKahRDBMKIp0FnVez0Nn7gVxBVvBRe+/bn9JRU8x+FKuOiOE6O6pGiqd0mQe1ID7hWMl7r"
794
+ "Kkn3gHZTcipB5JmYCXcWzVSxl6/hGOD5kpTM5DzWSih5RFXoBVrFpx5l2XItgrDyxxSq99JS"
795
+ "uFCv1tDK9k377Qe/lIC9OF779lWg8SqxQGSkzr18bkuWvGaNbIUWJXN2UhxzPME1kQWs0rzp"
796
+ "GYB+vriegJ/DVZoxa5XKoj+s4dMub06hF75GMpYUy+zX3AsklZKIqGHzzXSxS5eR147tX++3"
797
+ "H/rihL2Mel0iIpgfxsLBbM3MneEVXAt7OHIqtiQR5qcSVdUt5OKIBBy8kvb3HaMgoe3K2XvN"
798
+ "9ZFom9niKhlO1qj6O6jRTqZ+ik+z/RLSJ85RqdvR0ZHhwxhBwKtqewUl8gXx2re/Es9yXv7Q"
799
+ "C/KibuWyuJKxUGVi63LWMGPFQ4qpFYm4pCh8oHFpUEtktHm39+y9uCDGh/yxWdKCXOk7NrVc"
800
+ "hYZtyQSWjDro8Sl1+GRfbyUyNAz195szMBkPoeW41e1f7bdPe0EBexG89u2rEa7dLXqyTS6L"
801
+ "CbUSOLOf3imcZSxCFsriKqQwGuZ+7mzCqBPJeLKGpC1p1YVNElWkx3w4zWwlpPgDd/IKvyr3"
802
+ "Xjf4mIg7YcQikVcFalMj0eqm+bCmNdEeSrVnt4/tt894EcJeTL3sWlmwtk88ppN6Zb+VFCsK"
803
+ "m69cwsvTfRCGSN4gCYu2JCbUQmCRGpJk3Vq8DgVW3zd4L/7kRJuFETA3zko2DbkRwDx79Pgm"
804
+ "SK2FdDQD1MbHCVXPPJbWypHE2kOJUisvxMnz47Vvf9POnGGPVc8f1gVns7W3JS5U6dniW/AO"
805
+ "IqKN99OyFZkIQ42c0bDVXrM4rXhGVWzhvayyp/nEVqUwQkXrJIyQpFhssGIYwbY9jJKYwq2G"
806
+ "abnWSrE8jHBsWjFb3f7Zfvsxzy1gz4fXvv1tuL0Va+lQyQhSz8IWbS+XgyRswYFNVbI/G5qT"
807
+ "0ZMZYU86C7JGzth4Ff2bMdW/y+Pei+s+s0VUpVsxJVG73XuvU2txiuPlbnwaHNW0sLFQnT/0"
808
+ "5Q1Stn+833788xH2vOrFSeDsQnLoRZYrAMRH+VL22FotOUveK3ImKlT38WLCWLegnHEAZlbs"
809
+ "nveKVZLBmqlC1C0UGyfo5wKtxnI1c/fnGmbGq/GbDEpC4tU4hphcl7Vbx/LnLpHPgde+3bi1"
810
+ "yId1jbQtTf0sVCfeKwjVrF7xYWCLF04kjZCCBw/etV+ITzV4bV0YfP7wDNmqzWhhRG8e6YnX"
811
+ "PL55cKYFsSWPRf3W3OibdSsnpVXbhkLVUF0XyHXZbTRFR76//YP99pOeQ8Ceite+/X3kJCKg"
812
+ "w45kablmB5bqJm+K9OyOeq2VzGolFvbLrDqKN1C4Iem6pSJdAGHvFQ8wPoQSRksHNswDDUy1"
813
+ "y3TNYYTxtBrF1fd6zk5TPMHR11xYG/1g2gjw1zJnpmfYbvtteyphT1evuvxZJ9TckHHRnMrH"
814
+ "rF5SJhyXMkZe3ncqiRYXypmqfEv5Kp1aUvTTWg99JXeVBCzVRCuICSzhQlnJeGWbxbUphxEc"
815
+ "n8qkT1QErajNvoq9fxMdki+hXNtqvLzV5wpan4TXvn0twmDwkESwo4qtKl+Symj13eAvrycw"
816
+ "EXyL+lhoR04GH4wRiRlOmpDAwKh/PJM3P1qW3osONgY9lOx4AiPYE5F5L9QLlMbRk2g1yYrl"
817
+ "+nRWH6PNkph1SQsWza39lPJLgZTt7+y3n/4kAXuievlF4WM5SIfvApdJ25YSyK1CWyGXRWo3"
818
+ "BK+zgsx2KhO2Dils4KFSyN9uwHcZQJxCVsJhM7OVjsym725jnfUyXX3c6RycWinMALWsTyGG"
819
+ "0ALnpo2qoT+bKqDyNJ6Fr/OcHv9xvPbt67Doa/PdPNULscpiyyMcS3PGo8RkekkooJG2cB9p"
820
+ "M1jvtCJhV8ckEyZkwqSgAFJ1pFd0manoS6RteYG4ABlEgBRrpSESFJ8yVcKd1mqkbGygpakh"
821
+ "3LK25xRuCVt+az/qiJ3EXCvb39xvP+NxAXuKel0qAIdmWQTTDHuUXEz52bn0JLzOauK0JEPG"
822
+ "C58SUlQqkUm6IjqLGzkt+3aMERdr7r0uRfQEjbMwIg8lncdyreLT5KtafGhNRf5o1uEdlqsE"
823
+ "+kiKovr6JAF7BK99+xjoIhGrupBtFpyMwntltmgrQ8Z7kc2ZC1sqiyxmtl9JyWw3B+O1OjvN"
824
+ "YILO+HUlqi9sq28t8QM3OqJ4IKGl9tZ7neogdfjw2MDg6FOgyt7o3Fflh73RQKZq2QLw0lmp"
825
+ "y2hscPvq/fZZjwjYo+plf3Zgvok22hNqWa4SWJMhSwimoomJpOXCpG18ABrrJZ0FqTeDDMxc"
826
+ "P6tWn2p65Cwu98V+CxC+0JIJ2BRGIHcj6p8+CHFUaCfykAeWqNRg5Jf3H4AechuQnTumxCt4"
827
+ "/IMgg5bRxwXsHl779g3Rdcn0sz5uyOI+YCWYYVrwRBVWrLfgzHglvKLvcZVCaEjmeILv9a86"
828
+ "diu2GA8dayKTDaJKathvFkbUABbm8H0aEDG3GeduxEZplg9MjYFWqw7TkC7QvPkthUwiZH2m"
829
+ "le0v7beff0/A7qvXRaVrYTvqhI6JVkStzFxOdTDjSxVndvRggJYyRqix72GYels4XDynz5Oe"
830
+ "2QcrBQJdfz5sGHcGa6qPyzDibBSXgZUGRFg15DRBY6qFzeIuRQXFTzdiMSOFawUCNCNJaXNz"
831
+ "VsfFEF9Mvfbt3wIV/d8pT65DE3xZw6K7Yh0KRXPCaGztRN4WJixBlgij0x5z43E6v8PZquPv"
832
+ "djf+OgQT/yYz3FYT7U9scNf18gQNxCTiLD6dfT03Hpp/9WTCeChOslkeQOhLEGvioO3oh8n2"
833
+ "5/bbLzkVsDvqNUbdYFSljJTNc6My1ousVSvUwvKEJmnDndKZ3dhdDStYj6RgwrzBSOMpAA+r"
834
+ "0jHDkAnJGGNtZr//kanUC7SKT4VD+TSyeaqPfs4PtwpPAtJFy5EHR+iYVS+OhzIXX3VgIPgC"
835
+ "6oWphxFBexyFGb4zuXpsodio1yVS8U1Z2IQsWrZlETJMYC0SihhP2MN6oZbj9JWXYA22qvde"
836
+ "l9ClOOvWMpRPA0oFHm4FHWpxhXTGR9QnQ8qliLIJJozX51eNr1CeG699+2YeM2gzGCYX1mCE"
837
+ "/75BkM5TiSxapG3ZuvHDGTtaOJszUdoYMitVj4QU+gGKvsU4fwRj/fng4WMsWK74Nxmt95pT"
838
+ "U3P3J+NqchGcKiOHW6FLUTIc5ugbidMIVOGne4BJQlTBA1IU7m4WsX3FfvucdX08Uy8/w8wA"
839
+ "gv6gWDGXDujZjREuYVjY8oVLQ2YUTjVxbfaT9yIN4/NsC84H59RHvtfsvYQWFmvZmFTHExXN"
840
+ "1HOUFcOtfPURxMRLf1F7iOrPckY6h14BMm08Qt0VKo5jrHMQUkIKOvK5csfgL/Dat2/B8L/5"
841
+ "B40kZXVZ8eQqdf/ZGvQgvWrsKq6Sk4bdx4sNvkzVcEEYCVghcU2ZapBP3tsURoB3sqqF9TPG"
842
+ "OH6dcqWklKshsmcKPYO8MDYbA3mqUlYlm37Rxt+AWpqD+wLpeGH74/vtVy4EbKlefDkrAdFg"
843
+ "PytcusISWi1bsfOjP+wtY+vckC2anAzT7PFZ7YwwupTXCCkqWXu7VyvWD+10oa+kW6aOiGHE"
844
+ "6L1Wd8zGy6x9jCGWJ5MtGo9FRS6dFMT5woSU56LUTkza1mnzdmIE19e35HZt8Jd42WnyGZ0k"
845
+ "ab1RqYZM5tVWPOVAPy1PLo3lai5J9PLQFIjqBSuOHFJAQ/xVv9CYIe6fJelK3qvQW9PXsZk2"
846
+ "eq+NoWzqDTIsvFc8q4Iaj2abKHBvxSkZ/LUoPyva3Gal7NQ9lgb9tJqxeCzpmvDat28DXR3Z"
847
+ "ftAkV0zS0pDRFgpXt7k4cgY21c1g9u+qV3L9iyppB7KicNZ4zBqm756akwl0ro9cUfqNdWsV"
848
+ "RuQhpnT9rXZis4J5is7dqq1lFsmHtahDh7Uc2blzFW7jWWiaag1M3fL2pfvt1+T6OKuXjU5x"
849
+ "jJYMFV/HMEolI/m2oEn3C2jyVWWxMitWKJ0lzMx4QX8zxCbkMp6wY6N/jKd4r8GWXj2gldFa"
850
+ "PIkhzrLTWcmWNktStdJaFgpftFlcH9lmDZ+ubzGexcKWia0MHFZqFwZ/xsvTVJ0pEbjMRDJk"
851
+ "y5kSeVqhliQhg1gDTFnDZuaiFXNJIw0Turbq4s8skLu3YdA1frzZe81hxPxHpjiViB3V5p+4"
852
+ "J3F12jRZey2R8aSxmG+tXH87lDCs3JUWxHGvbcYDKmB2tMLL6H289u3/9gKYdnBaArqPrHil"
853
+ "w6ReSyLTflqVSNMefgsnqUTUmKcYf7j3IockS/vFlwRTv28vYUNmn9zuz8KI6gWxaRiRTq32"
854
+ "UVwsNuc2KzT94uB6lh+jxG2W8SdhRkjbWsVBWsgdAxbii6rXuC/b791vXxjqY1Kv8bN2tw6g"
855
+ "QKwgIvysvmTJX3pJxCK4+yV/hUC5I2YqS/5UjFt5O08KKaY+IhOwQrWV2eK3e1oY4SXvfnwa"
856
+ "wy2ZbVZy9DFKXSYU7sl0yweXTnsX0zZY36LVeb8/uD524c71MeHlDW9M9/PDBBNjBD2msUIk"
857
+ "vUsSgzOqmCSWveTPIlvZfiUl0+1YQQyneJDZ768qWv74A8g006z3GqKm3oekxvh0vrSp++XJ"
858
+ "deUKSObd65rNk7syX+UGKyIYHJVpGLcZ9dKbwtVTE5tO4dR+zOoFMrNlaJjoD+24nAE3K9xM"
859
+ "Ekvasr+SeU0kLTVMGfLoNTUqywoyDinKGM41UtaTq391D3yp4fMzpqyIUpH+yBRbe2swJvMe"
860
+ "O3zYdbmYTdaeQbECZ6xYTQxpFsVavjL0vcTLqBm1A8QoW7Te8OxF8xyvfXuWFAsrONKSSuvr"
861
+ "ci+s3Jys00tOJC24KyxIdYcXXxu0bWpL5qiCUFuUyIkw2HWEE+LRfnkYUVCo9zqGET7WeVkZ"
862
+ "hR6SKxqC1CbVqWvaHDWKHoSGPyRirMaNhzIajLyaIAihqJofR29Cbr9tv/0Wt1+sXuPifYZI"
863
+ "gSDcL1DDk72/gYIARKF1cu2bmHPLlWhLKYaVUa6eyyqpePUvXpYDDOl7yXTheym+taeFEevQ"
864
+ "IZ1pyAzF6KtR4Ztt1kxbyC/g9/ZeoiMZoQrUJjm222FbjpB1i34cyX0xXhfa05mSM2ISN4SF"
865
+ "7TOpsbAutTAaMjNwkpLV9JK6XoGRSjKWNYwgS83GNPzL2F14L2OLi6PWMm0t5sE2y/IXbdbY"
866
+ "/WSz8nB4QpBtVoCJ/RYPueGqF+tdM+dODUNR0A+xrsaxkePwnu9ov4J6wdt0BRGImYlHsTt7"
867
+ "4WpNCzltly/WXyUCjNqCpxrICI3HhFeBnPcR2WdrJauXea/C+9x1qxXNt2b1usNZHxXDwJFE"
868
+ "jXmyWRJtVovuyp464OwaSdCHBxZEWp3tyjS+VPOXC903oybitW/fPeFyBhbOn2UiFZfTwvpo"
869
+ "ulEyT4G8+96fX1LotWTLPLYgyLBK8KFLpE7n5MX2QdN7PvMnjQ08GZGM2WbNEqUr54yUaqXn"
870
+ "UmazLFOwtzsGB0fMTrlheMDf+lD1OpShIwZmBtYBCLbfuN++5JrUy/uCQDPz/R3sztQOdx/2"
871
+ "Qx+uSd4a4JewbzMiST8WzCX1ipGY1dNFSJEG3ds5jwjX92LRAs9DZGhVDiNOwi0vVdzbzTaL"
872
+ "Ay0E2lyHSHWkZFZSo8+SrQbyW6Z2ALT3OqBTcVh+axvUca39VUdj+2V4XUiYHmFL24ZC0WuI"
873
+ "TGcdwurhff6iMi1UDSdiVsNeDxp2FlWQhvUt1xhPLC4LPTUbtcEoRalixbI+nKkPcXnadHJa"
874
+ "ByvQFD1kJZtubPa5r7AhbsEclerZoV2KI9ZqqmFF6y+0jakQ9/bBhFcehDPP38Hu/grzBk2o"
875
+ "kg4RYc7ufVITc1PxuqNhoTJySEHXwmQZs5SOkSWwhus6j09zFk9pVj5pLDkt6qVm527N0sSH"
876
+ "YzqXP3NIdXg+M+8HYjqvuJhnz7rV30WIVG27THhd4DuysJDYlFx/slYg3Xph7OYbphmmR3+n"
877
+ "vAWqs0HD4om4uS1p8xjfLp2dJglfBQvKQmeFwwj19TmGsC6apZFaqg7ZrGZDmXnQFb3qONzI"
878
+ "h35G+DYDoFaOjVTxTRlbHaOuxweVb1iDVFFjvPbt+zMKEamw59I8r3a25hlbS+xMt7ic4VTh"
879
+ "5iAtMMc4xjzC255zHqYUcs+j1Uc+z1HU87kJm+LTk1FcQ5Dma4AX2tMnNsv5m0QraFUa+te7"
880
+ "qJVICxeoQ1qNWgv6xJrX1zkkADq08AJgvPbA9vn77cuuUPUy4yX3gVhSdR/BO8+eSdqdhcxN"
881
+ "vLlKnbcuQwugrmSM7NQ8/AtTxiZ8ozCC8y0aHvOozWIBW9qsAFPJEJiKjDJX9QQke0gRvJU/"
882
+ "az+ywzvU1yc7b6JlR8WD4GijUxVVR30NBet41eVOPZteCYLwFkDoJ6CaC6rXa1jTU+dVMmjY"
883
+ "iSFLGob5b0FarEqwNr0XrSk0cH5uJJrlarPNshpHLbhkswwyLmdi8sFkG4cAACAASURBVNZc"
884
+ "TlzeSKXYkD0oebDzHLk6K3wP4vP9h2x6hDw0HN1pXcb+PB4GglofB14vQ9ISxEdXfnm1myWt"
885
+ "tyXvojZ0a5a9KaSQ1EekuFeSz6Z/dB1jiPDihB+yWXNXtJc8GkflQhXP4clyNd/PRc2aeKo9"
886
+ "BqL36ojDd0jcSBnwjQIqOGQE96OyA60AFNIewsH9KI6rPS3UISjnICWeRv4e5+3l0u8LwPpE"
887
+ "Ly+mWE/EbgZuaciYpEnMhB5aJMYlEjqSwv1WHQuldt2SOYyYbFZbIXXHZnkcdfi+dBuEsHDR"
888
+ "uCPBc/07cEiom6FF2S1aPOEMFw9++721Bga1DaDmZ9Md/qh6MT1ne33e3+fw3bt/ysqznsUl"
889
+ "woDOt7piLrJlS3JIQYplSmmu6058al2H8czV+zbL7rPZAi1JM/AWXzLjfZ3eq3NoEfeV9eN1"
890
+ "fRofCf6OB8lSEzxIOD2kqYC5q6s4Dsbrwu013VvFIfT9Lqt5pkISAXfmnwvBO8CljS/bmDOI"
891
+ "CbWkYbRCPq2jEIjq6GlEV7P4lJ37+SmEs81aO/c0r2RYWOAJlg2914euTA8eW3TzxOsw5fZe"
892
+ "nIoNU1UhgoeHEMUdOtAIdTgwwmutXk8H5Q40d6YnbE1sq+fYiQV1PJ9KISJ5JS+RVbk0B1aI"
893
+ "M8smTLrUaQ2qprEPPjqPzvfKzUAaDsrCdsDv7VkrW0FCOP1ibqiRONjitxbKJmSEDod6LNGa"
894
+ "29lCRRMcB442WqnWkCw6Nt++7KN4vdj0vDjeh/L+FnD3nh/WvBGZB8rWCS+KZ/mPWzFb2rfY"
895
+ "zsIt62BufqyHZhrIXVlh0hkpOk7hcMKcNl2hWcTQW3B2X0YjsZHMNGWoce6FcRaQdSr0D2CJ"
896
+ "PC44HnAIcIGIX3hC1H6NdxQcsKsyPdu3z4w7hsUg64TWxMK6Qk/hZMn87MzQaAfoPIcUmBoZ"
897
+ "/sI7CN4Bjm81qpoxR61ITH96F+PnbzqW61Gb5dozOfdG6HAz0LuiuYuQ7FcXlYMSCg5I+2c4"
898
+ "qGd6ABQHjTmaBcehGwRBI4ObBwAVDw+jSo572j690faL9ttXXZ89XboeVYvnun/h6SmKeGfN"
899
+ "c+AMqWUeBvtDySpvJXZdFzVeNl5+OejqLE04uU/q0iwypXEyQvz1cIFHzoQ6yy7KGOripBuE"
900
+ "9vkModWW4AGUio8/qJeveqmmlr/XkEAAeNZ9Pe2Ref7OzPyq56Dkhe+fsvE7hTgtmRMyUrUU"
901
+ "Uri80Tmx5rTioCspoahx4UuZgomHS5ruWpYZt1zAAw20agUPBxU+2qZ5qX74mIVCj6+0I3K0"
902
+ "FTDEiYMxMYltY53DhE3fl/keHm7siOdQr3dnehkcl9hpT+XitCXuqVQHRmGEO3EeKpiCAytb"
903
+ "cwOQVxBv5QUFAhWj4r00Pa3t5czVi9J8TuofDsBqq+Ch+THATPSmycPHx0v6EnNUjbbcQezb"
904
+ "fziILTtUBO8pXs87PRFEnqmRsOqEoQA0MkItV2LlLFOw7CDlDp4vCI2y6h2IlE4dHx+xp7fs"
905
+ "ONqoOB5oVBYgXY3UffsSXd7lx0Tx0EilZxZu7cUpbNPW2Bfa+lQceeLiiKc9tVyegv47D5fz"
906
+ "KejHqmFxv2Q/33QGXHHvbyMp+GQyZULIU3t1O5uvIz032RA1VRZB9R35YL2BID+kKRfU2g+O"
907
+ "+wY1eTIIgvsmP26yZ3wMLqflASChhbHdwBqmeH3w1etlJrZoI3b2v1vG7b4oYKlY+D4TPIia"
908
+ "J2h/sw46EKuMbazTmXtogPotL2SKo5WwxvNTg8DkJ1slZkicsyRIrq/H9KoViAMvWdjlmoz7"
909
+ "S+yYl5yewv6dN6qr+dQ8nJfcubmxbcrEU+8l1LVhulukoZGRaqHlH+55nWkfe/1NS4reN5o/"
910
+ "uz9b53jCa4FjVJJnZvJ5alPJfHRHzvv1TthVnjDPn4QMeLjnglonFvtnMDIEuKx4vU+w6Mco"
911
+ "wOqvPb8XNzzP/dOnx7fzDO2R3zr5qXkXLueNrTo9u7RIjAvP8/r87k0DFQtFGbLy/D+VvYVE"
912
+ "pHq9qjLi8dKHBEJewua9jkleaP7+krNpdthn90m9eM+XUSKF5gG0gos66SJjN1d96lk02aXv"
913
+ "mwKIvrBABKUAQjgWNMEz3bhYH04Z+5G9PQoKUAS13FM+tuf2nWSFkSAEWFBjfVG2IChlQFbQ"
914
+ "PZa1GXumIfn+paZ5C4s9d3fJ0+fPltyfnrJ+L47tVHW4RDbgE3S+xJULrckogPTGXsK9y/aq"
915
+ "Eoup6H79hChF/SW2Zn95o1fxs4JADH/BGbK098YHkHFc9YZ/758SQbE2oJ2L0dMB1AhcvXt/"
916
+ "ie8Z9kqcP9uXb1g/XwTcZ2hoGLrCU4tuppwbMvup5qLWt/Ms+rCqKFxoC0IYgaitUXuYwvRG"
917
+ "6SsuiVmuYLXOsHY6RSErA6QCFO6Q9pvqGaCjzlUVIf6UTwekapG1+3kJ3b+did+XpeNR99HV"
918
+ "6wAmR5XUAnGXsFYZK8/icpCKsD23VyV7NPPHK/NqEmfmeX6j+T59kUIzojar0esLUApa8RXQ"
919
+ "UEF9iByuijqzxtgyJfrQR34+sZ7Sy8M966UBWvPyoAxnAvliUnpv/Wf9Jz+o63G5/+YNszjZ"
920
+ "TIk7uGjhM73hHdzoNEvEp8r07ne+2Z1faKlhplIXzUftILEP2frOkjGW3sgbL2+lCPVVdzfW"
921
+ "CDJACyXdS1xolRTi63ORzfPzz3A2P/1IcsTSjGl+vj9/9vE3HdOz67+4feRHbIj2WYBSIBK8"
922
+ "EU5aZELttbY6TGy3HVELMZW/MRVAsoez5cuvNbPFnkxIn2xJWC4Rsv7uggpIUWbsVaIOTOwc"
923
+ "RqESmS5AEg3Z3BTAuZ7Nqha0sNI88vyrn+jXdTG2e4n41tv1K9Hlo7TFxlicGvlokOTM++lC"
924
+ "r7XdfCH1AsmbxIfz97gvTvNqEt9U4kKDg2tijcttu6Xf+7jBIWmFACjGEHcgskqJGX/aJebM"
925
+ "HAUOO1IlRVjTVrb59TQXYgnu0E7HSMvDHpjn50gC07PBGD8D0NpAp8aXGgQXqnr8DvNAvOlb"
926
+ "+m62JWZink1FU+Iun7cGJsZERXx9IbZA22GkLHGoNkBcv07TFxQJbA3v1ZuQOhKnCCE1ekLE"
927
+ "G5W9+wV0TkdfE3oqhExFENE2AdPCKW+zjbue6Wo2n+2r3U+/Lhfi9XwlZEGIzwc+MJQoBvdc"
928
+ "U6xeFIXszDgzHxfalMT1G9VZrkfP6K2DqEzbn5ekjwH6JNy2yBUQLkWmW0ZYwfgTCaK+vgFV"
929
+ "TRhkQOYhhY0ObaDzzJQ50dGK4+9rmmDYedst7kt91dIA2X4980lpcgSR4ZBpy887+bFOCOr0"
930
+ "rO/PRgY87d07OXja07YRdlSJ50ov4WOqxSRMIuUzRuBfTNPXRFW6ndksmG7BCXO2rET24lhG"
931
+ "YWld4TikCPVRwE8Je/9YPZMzy/teZ2z/wXbn8h6PrTD3N4j/f69hUf0TLiSwz+ewaOAF8We4"
932
+ "RM4ykFazdZZBgyhtz3RhstgtyiFjMX8Jfnjm3JOMDbc0HTO23B6OPKL3GQhKHaJVKu3oQuVY"
933
+ "NKTwEXzMGV1xPvyJg2jIzIdxVMYe2QTMta1/Sls5acacTaQSKavVkOcfmVJjouZ53cIojkzG"
934
+ "MXkX0xKGk/foWUruu3nl3yXOy7QCpo9hW7Nil9qDiAdDpeNf2GbxVaiondhEXVd/YYXoiM6C"
935
+ "YaiK4jU226AhhTYb56y1MVicwZJF6wHuMG3n3p8lJDUeYV9V8rz/lLK+T9O9lWP7dz2NX5fU"
936
+ "q4zZbnhR9DjuzkN/dFuTP0o/pvkde3se3QjH3d83DlrOX2oubbPgXeLWeJ0mQaUYqRKNPL99"
937
+ "x0tkWEwPI6z10N+iEXnit2KDoedC2aZ2pbmxRuVmoEYwheoZd/Zy39vHcuzIfQSx0U+PuAIk"
938
+ "3jPWcWXWirCyvYSLo6Dpr171vmCxnyrNpLdK+5uViRmaNQ/xXVJmsVQv+63u2CzjKS2stJDb"
939
+ "if1+BF2cR1BkLxh4QHTjejmc4g1G3bSnX9M1w9mQOWoJqZOAo+/LVvK+N0YzduoFs5HinzIl"
940
+ "vayLtPfG250UX+H9LI7X9T/d9k/ZCJjsVCx3SJTw3l2mCemhDUNggBIiZ2zZzNJmjUJZ6DAm"
941
+ "hkpczd7DHH0xy1W0hbhkq6C18S4NRJiPpEhG3lqRChA3KtmNpQKKSgyxA1MJBGK6oTt+FiHH"
942
+ "It2DXsjzUfZstSc2NgUAbtcvdbyAYL/STp3np62NGdsNBh+3HzmO4vn0FrwFxKpXoAVrhZrf"
943
+ "otPyVmF/qBa+31XTrd6iLMMVBLYKHU5FP4Nt5zSkSM3JqVEpBBxoOdR+ITYCgiEjLLj7PLRD"
944
+ "7SUMhNHD2jMR4/zN2kY7LX2SIGCA4xWDe2YilUh7NrXdViSPdRahPBuyMkzP/C5LmxWoWpU/"
945
+ "UAABWjP7enX0NmNhxJAJiiT8TSkltR3aBGi4YKIqyJhVTMrGDLgz78/OLC0Je72Eh6ZwSRch"
946
+ "Cwph25fhevLCGT4rsjxv/PkOd7yaBEfV4oAZkD7ZPDPEq83Kx8SUM9WZSEKUokVNfILNCuGW"
947
+ "zctoxJiRAsZfJrK4qy7rY9ca814M2VlIkTQsNSrNnDWaN0PWf4LwR7Jpxhyb7WZGIaWybsL4"
948
+ "uJzqox/9U5F1Gu6uQPOkXhJ2YTLsBsdc1JitFrHDJH4hG2MNi9A8glSnYVrTY09ajb/yHJ+a"
949
+ "qe9Nwm68Olt9CGGwbiZpvHeEIBshhYb1c9zKumWjXpdgCW0BEbUEEzcw01AzUyzrm/KHxl+E"
950
+ "DPat7hdZTKUWvjDhdf3ft498543BGzRQ5WLzPssPouBZ69KQWioWE5nC22XhC1uYVsg2K60T"
951
+ "FWtQJRDRvzXV96w4W4Eqro9s7SXcCkvU4gITJdbX82GJbZKoYOqjIeMKldKNxt7faqgCMWa4"
952
+ "AUjreAk27OZGaMKu3q6/O+MF2DVzsiU32hoN7ZrrJssYJxe878dnYIGhDubnslkGXKfkzGaF"
953
+ "L2ABBMYxXE/CiFa1GVHym46g1dSxH3t2HRMQYc2SsBVk4TapWi6CjzkzjtBgO54Nmf2CLEvx"
954
+ "oS0MuNg9r5OaBbpwGsFB4/nCH4MZb9Srw6BNKwXXzWV2Jb5J3+vzOrzQn5W1zvkenXNX/YQW"
955
+ "OlQl2MWM8dJ7UbtZ+y4rBFDnrEfKhaSLUda3KKI1tIcUIdyq+tep9bPOVKWGpEcbBBa7NJM9"
956
+ "6DGBElFbwkTFzr2/fgdulqYhQ6ZkYSGUYJNAGZSc4QVxFbEfFKRMupvWoCC+JKSvk81KDJ0i"
957
+ "dUJb4izVU6OKzVbAq4+J0DDCA/rEVlSvpoMmbL/Y3qmiYiZKGFt7fzj95dhE3jIS8xYoG3zq"
958
+ "I+enDCYTFQs+bAamRpSysv5ZDxUL1cCIK2k7T1YjXtd222WzAQuG1LCA2uxK4ercsc0MIT5k"
959
+ "m2U1cbZZa9qIMyvfC4z6Q4pP7SnBOO2nQjnoYyRrjiQCWyV8ntZQUnAfHVgPKaroaOlFK5Iu"
960
+ "Dd8mCnOaP6mX0ZYxmuJZBm4O0oKRUm4YoGaytNRCrIwXbtcvXuMFjIFfEnehIcKTwZT8OBIc"
961
+ "FKa/vM2qar2xslmWvgbCSLTmMKICUoGmspSSCE0onOm+X2bvpZWBr+JbBK5bi7h1/iMuyYFF"
962
+ "CoMbM4y62qkIheQiNiOMkjk/a6ZkESBEOXSq+GEM1aYp4tV8j/qeLqOVNOihtjqTx6wsyxym"
963
+ "mUdsFnTnRYjzEFMJ61d2YFZDJSwZ9cu4L6gV7fAGo9XEVB97j1CjAau+nARMb6X4X0GLJAmn"
964
+ "EojlMjqw5OhDGNvf0oxdtE2BJDKCWYSstWhognjVly/HCM2hWk7QE17ihPGyJR+Ixa6eyI9u"
965
+ "1VdYRAz2I0h+iqFZxhb3wq1JsURbi0X8D1/nMMI0DB6G+VvT+bT2AS4nhBWGJkjRSZdRSMhY"
966
+ "hMpEFTMq/k0Whiw6fRZCaPABJdW4aRLqoOGLO97fuDjB6/qJt/3bt3R2q72Qf+UOwTyAYlaj"
967
+ "pv1CTQdpSdz4MtA6816I4TumcKuDNVfG1FocYQS8wTjCiDrY8kiCCEPVv4sN3Zq+aYWOOmne"
968
+ "hBRYSJEgo6jC41ZSMiMsq445M0MnXUA/tQlqRCo6tkd6Ng1BZIWzYWr2RhCg3q6//h5eAHDQ"
969
+ "r0mZglmxxKfQCkXCOmkmMYfJ1KcK2Ohd2Fd5a1HoQ+hkYKXK6Ol8f3HRMMIu8XcEa+8ZGL/j"
970
+ "gRIzUXddqli4E1KEqGLSrVCh2I0ZczwClnUreX9qhJ4hNZjgGdIzJ5g2yxIVFAv+zadpwkt9"
971
+ "SVhStMhOqBkZ8wDXpD1pV83Asakq0wuxcl05PlX+lroFtfNN+3yq7RG9BqA3GzEG57gP6xrc"
972
+ "xvhKYXdIkHFI0d/xJKSYR+ywx5eJOQTBCGeLrFqLNtNOkDqrnsLRCzmwuVcKCFCupozX9Xvc"
973
+ "9v++BU0iaDCO/AAB7MPMDukMqUhSI31icNnd+6ZiSQpKdoKXcBihJ15bJBmsi7LF9dG/QtH9"
974
+ "Qjra6F1Yxka7quESEodlEkachWZjXBgwtaoXwWpT2QqKyM/SzCx1lpBxy3GdbgzCbtdf/The"
975
+ "gyl9CxOMS/yh4XszIBhApMLHxNhescAiaCHLFUGGO+HWymwhxaf6VA8jejsxJPWM1In3cgHT"
976
+ "5aZbIQmzPqL+1BhJMWlVvp8S1xSGLRuVXklPyqtrUsRuvobUbMjA9VTOiynmNuM5XjJ+QUQy"
977
+ "AiV6+DJ59WzlqUUZVo4lr9jBw7ol4ePZDNv8JFqGF4cR/RQgkZFID8hUwELDUNOvrL62m8xj"
978
+ "sW5Bl0cNk9zVHZUsRxXcwEz2axmPUR0Mzin68fmEpUcNWSN3L5SQpSIrvFcew+v6fW77f9yg"
979
+ "fitBxgJmS2YszpqQSRSxIg+zzWIt5KfIwvtMHC0oFEaU4udbFB4/aDaLHf259+LDzOu1auQl"
980
+ "EdYgmAbjy0lIwSWMy2KwWYlUClo5jM0FNFq3eaEVfn8qpf9cT/VbAABu1899Kl59t5mA5Taj"
981
+ "jJmzmsg4NspFK+0k5smpumOzELe+GhsIa5FMY7mGbln3ItXEpgO8ZrYW3gtD2Ibg6SHt30i0"
982
+ "3GvvkIcUi65uqKjMBotEK9e+uIIBFAKwqElr7594iiWY1e7eULMyXNrJtMbr+gNu+zdtEoUK"
983
+ "9EM3uzKg6KhOyTvDkYqQhb1FaRZjtAi3piQidyyu4lObgRBb9HfvalEXmIyXccNaRR1ciLlX"
984
+ "IsxRE4D7uZPf8pCCFCvpFsetQZxmQxbHU8jK5jfmKUpUI2WVSNLakHVJw+36Oc+HV0fJKwL8"
985
+ "MqoMxxI72+sJskVp6xsXnzeGluHW3E4M3mt1X9UhoTPE1eAApqTeqqSVRTb142FVZS3hxCFM"
986
+ "Z6dlyJoStoZs2dVtKmXCM9uvFInNYytmm6+/I4dnoFeF5IxmwnDFe6b+MbxkXDmHa5+xAiWJ"
987
+ "NQlRlnLtsxXmsQ+ptchNwhg6jIVn7cSTMKIYW9Z7rb/5ki0rgo6amYEKOfQYKN7jaWVxTVg/"
988
+ "VsdICiIshxS2a1cVM91Sy3FpyFrUpLUhm5NYylfXEkgvfzG8rj/ktn/DJp2zSbFaGoqjjakZ"
989
+ "qbJCrUYlK/Ehk2Si5ctV3k7xojBCZHRejQGG/fCzVAJxp8Cbjf0eCJ9cgHbkQWCOEZywtgwp"
990
+ "Rom0/Y1QEIUVq5GEJImKhixU1WjIgvww0KmeTja/xbZkqq3WqEQBLrfrZ78IXv2nlUY00G9i"
991
+ "rj83D2NpSy9htpJtMm6YPNthYPulq6UGY1IsaGuxdiEvoxRW0UCVHS1UyaCqBl0YD4yiDgyF"
992
+ "+h/tW0drP8cTg7BmmrnK7gNn9Czrlpc/qnpz9BUMGdXEBFZYQUZs4zwlyDphl0kJnhOv66fd"
993
+ "9q/frBRagbA9vaiJyklo9E1WPXeqJH2KH5stfOGNCABCKo7lstZiKXoZkhqSiMxWqo+xJlpl"
994
+ "HJlqVTtVQ4MxnZ3WhJTMqqR7/Kod0lhY+2zzT8ZQcGYWDFnsWVo4+tQU4GQfoeVoL/HaWvvw"
995
+ "itv15704Xn2Pdmfai4s1JIPhjZUx2CxuVaUKuLJZQecItVmrgGC2kOJTrpL2k/KwwRIiCSOm"
996
+ "TPUxSFfDpTtgHVEoh37xBtiPIIE5CylAnD0+Hp/N2bpczolr1K0W3RKPgF0Or0g84axEUhPy"
997
+ "sekRvK4/6rZ/nQtY352Wiwbh0WclLqyxMuY0i5v3Rkl/IbcxhRqkkSfTRaH41HTOB3XZ4arD"
998
+ "BnMkcQBs6kv4dv75j3GBoNBgpMK9PDvNadNf59K0WudAa0ofUkNSCClXI2R0kiFzZWJPUBxZ"
999
+ "sD5hkjqupMPD3q6f9bJ49R1pDgzJZpXAU7JZYWFEx/hglUoFdHgs7QnAFG5B542nTpj5ng6B"
1000
+ "yZVBNthS0ZJUFslytRIPjE5e09NrVa7CfAMs3z/hDDJakbnYJci6osy27F5zcmKulYBFcGDV"
1001
+ "L7q5tvx1/Ild3mDPJu42GJ8Dr+uPve1fuxk3eIJzZ6v+qM0q9DCUS8NOwgqNroAqGAYLpFsu"
1002
+ "Y6mdGGVimC3J1j55r/k4qeq3gnSRte8/yMWak1NI0aSfVFJKMD0zbdX/dmRmq4aaaLFWzsPI"
1003
+ "hEk0Z7JyY0HtkvenAgrcrh95NXgBQHPj1eYxM08ZqjUJFa+Q/hDGOj41HK32nYQRfOL1cI2U"
1004
+ "1EtUrMSWmy19GCojhj5ZNgGu9S1k9+OQEFKyFjRMRkjB+rGEzNCJ3ZRz4sqceTVs8cBKz6rC"
1005
+ "BTfGNdHAIoP/BNf1HHhdf+Jt/5qt/4gsNinONu0pjFoizx5KeItEGGuVUzUj1QUMOq+QVXG5"
1006
+ "ajZs0LRK7rIV62OojNDGI1+HnAlbnZ2mWrWOKmJXN1GyLJecaflqmJaklmbsDp8NWaDKOK6Z"
1007
+ "tla0F+invUq8+tSORcq1GIQjMdwiQUpZV7L5VcsKiLMcn1oPjyLFuZf1AoFGokLNlqQbYpUk"
1008
+ "1PyYmXOvhkvRPEGGQIIiCa+YdtpVC+XSIVue0j0KnFWiOQ+rpzKW4UsDyLhRWVTGJVMV1lz1"
1009
+ "iK//cNnL4XX9qbf9724mTgmyPp3arKl5iPOxgakXKImWyKCwX/bNuhRFUUMKIw60ohe94Ugi"
1010
+ "OTCsHp7nXgBK1a+pehy8V0OBfzYzZGgYJ32chRSuWGqrZ++VIgw29cHdJzWKMtbrZm4WrEaP"
1011
+ "ccsUl9v1p7x6vABcf9pt/9tbnXhi0cKJzTqjyksk6xAtT3h1npZhhPUCXczIjxa0hg566CKx"
1012
+ "pS7N2YqFkqWrYhgPP5m2xSak/Rp6JNwPKYrEPx6TZ+i8D7539UpNy1UYlvOICR1vVLZFVfU1"
1013
+ "5Xb9yU8HBs+FFzA8PutWsFkEWVGXw5EYtwMMyhk+RjBfSZAUi72XmfoKja+IGwu6fCEo8Yok"
1014
+ "NbpsSfJefeY4gOLidCnu5QNPCtlZPOGcPSmkiHGXs9Xc+DN58/VRWtpCLHwmh0HDFNnh6J+j"
1015
+ "LL4IXteP3Pa/sS3t1x2bldec1MsTr/NwK1+XCy5dEC+Ohb08uXv7m4x9OE0a4NU46Fp5r+Tu"
1016
+ "ezsUTWWv+FE3NImQ4ibkvZAihewLyMqapKBbbLYmo8ZLEjr57RRoa1cCt+uPe714Abj+rNv+"
1017
+ "17bERyGkgs3SFXgm1Ee1WTUC2qwvxZ61wc0965IgdT7qhn4ihwxjDJwnFMxWCrqi95J0q2gf"
1018
+ "R6ldcryvCUJnb3PcBXXxVjqnMRTuwEIrElFCpqgiRPOcSsy5F8JCKYHOkHrElbUmQsoLsIUX"
1019
+ "wAvIJdKkazni1GN97l6cslOkmohxWLeIFOAF0dxxoRzVElQYQ9q+K2S/ZraS0+IVwB6/oVa0"
1020
+ "B/0kQj8FKZOt7K1jJQxzPze3Ir2fe1YaFqoW8oWlG8sLDcc4sMfey7RTYmFt9YkZ/Ty9CF7X"
1021
+ "n3vb/+LmcsUWKj7MY5qJqjk7BaUPgLsrWx7GoGLMm6m/KFJAaCeGG3uyQlWS6+DkvdLtOOi0"
1022
+ "PPb1COUvW7EI2cWsPYlZ/ivdASAeBhgVa55JGWkuo1woMbE4DfxCvV0//QU4wQuqF3D9Bbf9"
1023
+ "K7dgs+ZOaGLLWgBBt2QEVHO7kgMIvgfl9WLDuTBAKdpRPf6yeoIMq3n2XiZmhn70XiOeUIj5"
1024
+ "zw15K2cOI5LOKWG1ARRStD5aGisOzkKK4LrOZIwlkBKynHJZTK/dUIrg7fppLwYJXhgvABDv"
1025
+ "BuFKl/sQ7VCmmZydim+Vxzv0+1Qo2dRzGIHqBbHpeWZN1oFq48GDXB8JO0YqeK8DAEpFbeO1"
1026
+ "TfyKZd2KMWGi/e5zas+Bftezy5NCihVkzYop26+paZluYbWoYe35+n+W04vjdf3Ft/3Pbuy6"
1027
+ "mCSuidlgcdc1ixbXRHhlRLT2hXqEgGG8zF2lmgj+JaF/77NMfmtVH5MbC3aKZrq961ctdPtV"
1028
+ "glaNnyVe4XcVT3TgWLTmgmjpFAJkHFWkDu9EYUgu5vDCmgu9tfhDXpgQvJR6Addfdtu/YmPP"
1029
+ "Ptss6wi3ZxfxqZY80WJXWefI2osNkeCRg0oSjIY6fiL+q582wKsg9mpPXp6zCZkEzB8WJanv"
1030
+ "6EM/VaHUPtqvplsJIUVuS/aQQjykCIUyyZX+vhmj2Im5rIxJqIJM9tbiS7GFl8QLAATtiD2P"
1031
+ "5uspMs2NSo6yoEu48ZgUK5p6VzUKIwZMQnu9umK5jBEWTR1bU/eW5SrlXqpPHVZvDKpjg2gT"
1032
+ "1c5RUGXyJqRyNrQwyVg/pdto8E9DoATjNaUPwcufpBK5/zF2FkmD1Nv1B70sGy+P1/WX3/Yv"
1033
+ "31qjRVGibElY+IT41BQLcN2y4iiKWjjxOioWRxLjZooVK6PJXqNuR0zSNa7vJQB9u+T9vbUI"
1034
+ "xyhY+5XxAtsyDymST6qnkAXa5hGIsep5cUypB436ejnLZdNLqxdw/dzb/sc2NyUEk9fNSBUj"
1035
+ "yMwVtl+GlBqs1iAIpt7GOkNrIhJhRWslwp5ikkZC8Vg2wd4raEHFGQAAC5JJREFURDAkeBal"
1036
+ "el8Q5fhu18iEBciaczaFFGq5TMlmDRsi1PLyNkuUEiapVlZNIj715cHAK8ELwPXzbvuXbS3p"
1037
+ "lj5M3itbLupPTFo1llsYoSXGrh9e9OSfLlG9nYg6sTUn9ekiXma2ovdKjccUT0CL4PhDvjbi"
1038
+ "stFpKdR4HC3NFFKcPFx0RLLMWAtxrWE1a5UQUi0CannHOFIvt+v3eiVU4FXhBeD6+bf9Dylh"
1039
+ "VPL6VCJwLeLFY7ZgWsVhBNVK7wXqokWaBK6JpmFqs7zZmNJUdvcsRTxPNyhhRbsKhgiV0IE9"
1040
+ "miZtfKNHQwoGaxxXS6flhTJeNyCL2dS9E1CLfUfUVrhdv+erQgKvEC8A1y+47b9/k1TykGsi"
1041
+ "NFkAgm5JjE8rHf3WdW1pKv+RKesF4rK4iCT0z23YwpI0jNxYromxIdmH5bSGi252VMDipdBt"
1042
+ "VjT1nTC7SFM448NSDAspwslhE2eZpDkPO0lcF09VCG7X7/YKecCrxQvA9dfd9t+75YZhqokT"
1043
+ "Xr3SnfUzJkNmQZffZPxcRQnzvN6cu0TdMrtGqDlMPK4w3Yo6ql4B2+DpUgFttGJCahxarG1m"
1044
+ "HxHAWnR1Z9Fa0db0a8yG7A5nEdZXzhZeOV4Arl9423/3tmgYcmvL8KJ7TGEEYxd6gcri5J/+"
1045
+ "m8PGRxzh2UZghbIoka3ovWbLNVbWV3Wd7m1Jbi3a1xSVMVAeEUqhYdfO+7n9lIrmRXPWsBS3"
1046
+ "PnqKETUIbtfv/MpJwOvAq0/tiNEogLOxgaswwmag61vvtUALnyJSJ8j48K6JrWjtja25LLrf"
1047
+ "nwulEmZ10IJiUaQgXtyFhKpZphpjMFg/d6MwdhFSWJRKrivLVV+nBYx8Jg74aeV2/U6vCYPX"
1048
+ "gtf1N93237H1uDVVybluptEQHSwulCZaYx3zWCZXrFKab41hg3XBFpOEEkg6K4vLxuPAqCtl"
1049
+ "HRkpaM3K/Y9wqfNM1dKK1M9tkEn/80TxG5ogJ2u/rIxrDfNKers+9xjUp0+vS72uX3QDsH/x"
1050
+ "NodbaUnCy8MIgWgrkjsZK3VdQ8MIP4Gx6Az/GYRJt/xs7OKC5AzNf8Zx6hrS8j6Y4K6LRpAZ"
1051
+ "WHNqX7Xch1Siu7ppUOvqunM6MmzR/0NCxWnZoia2vOde6fS68OrT9bff9t+8pQqICSm+5zCC"
1052
+ "YwhwCqDOPaUPDtNEVXZgFEl4fYS/PDUVA1i0gr9WL3XjBkm8hrqMMTeqUuAwLNky7Req3hEZ"
1053
+ "NSwXRAStSqjFqOJ2fXitex+vKvu/M11/160d6DfRmXQ7HtAOtAdd8oDjwHGgtbCONEhDO4A2"
1054
+ "5u3WpiXjdtA6hy6JM4irjeVH2GzTe0C30yBC30s30h4gAjkAoXfk950+G+bPbyuLL1REuiYp"
1055
+ "VUfCCDgqWh3LDyqI3oSskHq7fsfr3vV4A3gBuP6eWwfroHsjKWD3oM8+QPrDhwHf4MP2us0r"
1056
+ "IrxOO/Lu9D0tg1rbiy2u0OI+9k0dkAPHxx2XPiTa15lpfoiwEoUSvwL0QPLPIPFIaBAhwg66"
1057
+ "DxhVmqm6cobsdv32N7Df8WbwAnD9fbd+ZBtSxwMd+kvgHvJCjJ+Y1Et3TFcLUWFDIobY4n3W"
1058
+ "lNSwJuNyIpCDaahWKStdYpseD13eOGXgLyvTBg1B8Kci1DJMpkbLKCtw5jX0dv3WN7PT8cbw"
1059
+ "AnD9A7dRLyJVVhmPuTg++J5GcwJa3OtoURWshgoJxiROLVXPI1co060kYE7Jx30hoCr4EF8u"
1060
+ "Ua4kvGmbIObvCPGHsUSWIV0sWkd1MVvcqrL1P97YHsebxAvA9UsDYUGfzpwZFUdzKog7hqub"
1061
+ "3QfrI3GXq+x5eZ28V4veK2D3EN+XZNhXk3g8PKyqp8kV66vJlSpZN/i2QpSuSbTaamG/x+V2"
1062
+ "/ZY3ubvxuluO83T9wzcA++duheJToUvu2pgI7t4GnZ3V7O+1YGQQiGGEjZ4oaXlqNlrQFduP"
1063
+ "bXWOUJuGExY9w7FAoy8LHaBDVQtdTU7TijsDWXNIEUZPeFpWc5uRW5Hr9uPt+s1veEf36Y2q"
1064
+ "l03XL7+Z+TWnZZZfVA+OBxwrgTFhyNYqlhgWDFe7aJZzfeQiGC1X60KVNOyI87OjEq1x9FG9"
1065
+ "8Rs/efeCi4rJ6tsg3X71FiI3IdnCH5UK4r9/K3sZbwsvANc/PQplyiOYsxat+rK4hN0ZV3N3"
1066
+ "dYSZgNoKX9/N0Xv1mrt8bXKETHmb3zTRHDmzL7t4iR9g3WbhtEqO+8vt+u/e1i7Gmy+OPF3/"
1067
+ "zA3A/ou3o9EYVM0Y7bLhtaBV6gXS2lS19jWs/wwCYjSf0lTveUSomCE+nTuFNOUuOsSIB6/m"
1068
+ "Pko6regSs/sxMK6ddnKj91HaClYudSZ2dadhzb0gfuPb2KthemvqZdP1z0e/H6XLwgj2wi4e"
1069
+ "FEZke95IUU4euuqwRLVJXeiWloyPJ7TQ/P4D0Ovmg3/s8OFj+zGUePrASE+5gM1twwqxgvgv"
1070
+ "3/aOBd4FvABc/8INgtY0jHjIv3iLVcNL4UnD3v0N7UWva8nfTNWKa2UOMngHQw2ZNVR5C2ab"
1071
+ "xFuvoCYhw+RbMH3SD+/0y3i4aEVyJIHL7fr1b3uXjultFkeern/5BmD/rK0dsMvdVL6ch7YT"
1072
+ "rdMahYYN6nwvlK34yC17eW4k0riJBq+evOSsM3tcpvBA7cMSGxpwKWiHXjynF99GI6Sb1kTB"
1073
+ "BQB3L+owinBNihb6ucXGLYq+tk1nE6Herv/kre7GPL0rePXp+tU3APtHNuFT+OlSg+OermrZ"
1074
+ "QwfRIak2Jif4MEaHxqkm78VmC2UBllHYHnTErF0HoKEU1DZyhIFv049kVzqh5EImwiye4PtE"
1075
+ "W4P3c0NQu/2C3K5f+zb33Mn0ThTHNF3/1k3PZdCakmoTuZbG9Su2EL3kxVZYaBhSv1Aj75U8"
1076
+ "Fj8ctVs8j2gP/qb2Ru3j9Bms81u/UUuNzTMrRluYg9nuTYF6u/6Dt73T1tO7pV42/a3rDcDP"
1077
+ "3rdx1NIYr+Wt2SguoSFfLFE0IKefRhbkqpA+Fbo/EzBLR1WHoJXRFEuEAl6TXmTFskFvOVmN"
1078
+ "YoY2tR+BA/ia6+3t7qn70zuKV5/++vUG4OftWy8KlUcLluGB7D6Uwum8oPXMufeabyOgNy+F"
1079
+ "SGQb3Q/jeLBSaH8Xp1HogPFiG3LY4xg03Wzze9ty0/frWH/tuw1Wn95pvPr0l683AJ9NSmZ+"
1080
+ "K/T/TGwNreJeoKhhUggsU5cJuxRrVTVnTc/vHTNFL9YFUi/rm4qyBABCJC3Ps13egH/yPoDV"
1081
+ "p/cArz595fUG4JcZZKk46sUmml5SlZuNzJD3LSp8btgBKHnLoc8MXAEu2u3o7cROQB2c2ch6"
1082
+ "QEXL6qDNE2EpVs1xK/Cx9wesPr03ePXpz15vAH7FvtkvzhfAGWOjLYNQ7MDixPVRvJGYG4wl"
1083
+ "8LQul3RNr85EtUvem7XiRiIAkEaqVnn3dou0wT3WN7xvYPXpPcOrT39af+tfRWLW6Jwzi7VQ"
1084
+ "opKB2LJ44uQcoVNTD/qjaP1KheOfP/RSyDxBYwuip8H7i8IZ24IGfNP7SZVN7yVeNv2R6w3A"
1085
+ "F+xb75lJOWquhtb5OEWs3FQETjlLPY9Fzw0S6n8UxMInQeeaXfaMrpZjCz19Bb75PQerT+83"
1086
+ "Xn36Q7onfsO+QagIElue3Sdfn7KJ2GycwQoO7Bg49qlIhqzPHA3PKtpD4OnChKlWCfDfPxBU"
1087
+ "2fRBwMum36P75reoOfMKqEhhqo88UKLRaY93wEoP+zSsVcvr9Ey4ml3D8Gp2xYMGfPsHiyqb"
1088
+ "ykc/+tG3/Rle7/Ql+9YvVHHpt4Jq90AtY3mfGfe6ctXbJd0XXApqC8/aq/pftrKVi+gKLayM"
1089
+ "DyhSPH3w8eLpD+5bBmUGjilc4lVRWgbuUpyqS0E5dJviqxXgkz4ESPH04cIrTX8y0rZQqZOn"
1090
+ "GLXKVElYoQCf+iHjKU0farzuTF+9b/cJs4UF+JEfbobuTP8PvRhXFuF66lUAAAAASUVORK5C"
1091
+ "YII=")
1092
+
1093
+ #----------------------------------------------------------------------
1094
+ RGBCubeImage = PyEmbeddedImage(
1095
+ "iVBORw0KGgoAAAANSUhEUgAAAL4AAAC+CAIAAAAEFiLKAAAAA3NCSVQICAjb4U/gAAAWGUlE"
1096
+ "QVR4nO1df+g0xXn/zD5qWzR/qBQlRZQSSSumIbZUli4y0L6lNAqNaUkiIRpItSVSKi+0Fpsm"
1097
+ "oCmSWtJYIUmbxgZepMGS2hQ0JU0zhA3S8KbBJBClQQzBUg1Jg00wUfemf8zt7jO/du/ue3c7"
1098
+ "ezcfRJ7v3N7s7MxnPvM8z8zeK5RSyMhYH8XUDciYKzJ1MjZEpk7GhsjUydgQmTpDkFJO3YR0"
1099
+ "kakThZRSZ/bEkakThuENgMyeGDJ1Auh4Y5DZE0SmjgvDEmH/h8weDyJnk4OoTkk0oEY3gmr1"
1100
+ "71M3J0WcM3UDkkN1vcTLaAAABDRAKU8Rilr968QtSwyZOj2qN0kslqRZtIWdUcrrCVSrf56g"
1101
+ "ZUkiUwcAqrf1SmO40rQfNfaVpXwTgWr1j/trXKo4dupU73CVJqY6HKV8G4FqdWbn7UsYx0ud"
1102
+ "6taw0gyrDkcp30GgWj24qyamjWOkTvVuiWaENMOqw1HKWwlFrT6y5VYmj+OiTnVa4qWVSLOK"
1103
+ "6nCU8t2EolZ/vZ2GzgHHQp3qzlWVZl3V4SjlaUJRq784UVtngsOnTvXecZ/m5KrDUco7CUWt"
1104
+ "/nyT5s4Hh0yd6p6h6GnYPgl1DEr5XgLV6s82rSB1HCZ1qvs2V5qTLFg+SnkPgWr1JyerJkUc"
1105
+ "GnWqD51UaU6+YPko5X0EqtUd26gsFRwOdaqPbkdptqs6HKX8EIFqdfv2qpwSh0Cd6uObRE/D"
1106
+ "pNmu6nCU8qOEola/u+2K9415U6d6aL08zeqk2YXqcJTy44SiVrfspvp9YK7UqR7eldLsWnU4"
1107
+ "SvkQoajVW3d5k11hftSpPr19n2b/qsNRyocJRa3evPtbbRNzok712DajpxRUh6OUnyZQrd64"
1108
+ "rxueFPOgTvX5/SnN/lWHo5SPEahWv77f226C1KlT1ftWmqlUh6OUnydQra6b4uarIl3qVGen"
1109
+ "UZptbUScHKWsCVSrcromDCFF6lRP7CN62s9GxMlRyrOEolbXTN0QF2lRp3pqt3maqTYiTo5S"
1110
+ "PkEoavW6qRvSIxXqVE+nojSpqQ5HKZ8iFLW6cuqGAClQp3p2ep8mNTd5GKV8mlDU6oppmzEl"
1111
+ "darnp4ye0gzOV0cpnyVQrS6dqgHTUKd6IV2lSV91OEr5PIFqdfH+b71v6lQvpq40c1EdjlK+"
1112
+ "QKBanb/Pm+6POpWeh9LMS3U4SvkigWp13n5utw/qVOdINGg0MB/SzJE6BqXUhKJWevzSk2G3"
1113
+ "1KkukHgJzQKYG2nmtWD5KOU5hKJWL+3uFruiTnWhRDNj0sxXdThKeQGhqNULu6h8+9SpLpV4"
1114
+ "efakmbvqcJTyQkJRq+9ut9ptUqe6TGKBpgHmT5rDUB2OUl5KoFo9u60Kt0Od6kqJlw+KNIek"
1115
+ "OhylvIxAtXrm5FWdlDrVVYemNIeqOhylvJJAtXryJJVsTp3qmsNUmsNWHY5SXkWgWn1ts69v"
1116
+ "Qp3q2kOIno5ZdThKeQ2hqNXZdb+4NnWqUh4DaY5BdThKeS2hqNXjq39lbeo0x0Ga41GdjbE2"
1117
+ "dRbHQZpMnVHsSnXmTppjW7A2wPZV5zBIk1VnFNtUnUMiTVadUWxHdQ6PNFl1RnFS1TlU0mTV"
1118
+ "GcXmqnPYpMmqM4pNVOcYSJNVZxT7SAnOkTRZdUax25TgfEmTqTOKdDciUlgWuZHhIMWNiBRI"
1119
+ "k1VnFGltRKRDmqw6o0hlIyI10mTVGcX0GxFpkiarziim3IhImTRZdUYxzUZE+qTJqjOKfW9E"
1120
+ "zIU0WXVGsb+NiHmRJqvOKNJNCaawLHIjw0GKKcEUSJOpM4q0UoLpkCYvWKNIJSWYGmmOU3XE"
1121
+ "OhdPnxJMkzTHqTprsSGfTR76lBsZDvLZ5CGbGxkO8tnkIZsbGQ7y2eQhmxsZDvLZ5CGbGxkO"
1122
+ "8tnkoW8hUyeOdDciUlgWuZHhIMWNiBRIk1VnFGltRKRDmqw6o0hlIyI10mTVGcX0GxFpkiar"
1123
+ "zijy2eQhmxsZDvLZ5CGbGxkO8tnkIZsbGQ7y2eQhmxsZDtJNCaawLHIjw0GKKcEUSJOpM4q0"
1124
+ "UoLpkCYvWKNIJSWYGmmy6oxi+pRgmqTJqjOKfDZ56FNuZDjIZ5OHbG5kOMhnk4dsbmQ4yGeT"
1125
+ "h2xuZDjIZ5OHbG5kOMhnk4e+hUydONLdiEhhWeRGhoMUNyJSIE1WnVGktRGRDmmy6owilY2I"
1126
+ "1EiTVWcU029EpEmarDqjyGeTh2xuZDjIZ5OHbG5kOMhnk4dsbmQ4yGeTo7ZuNIBGN0KchwwP"
1127
+ "6aYEpyTNjzQAcZ5AUwDQugEgxKvcvjhupJgSnJI039cAxPkCTYGiAAiAoJ8EoPWPAAhxkd8n"
1128
+ "x4m0UoJTkuY7GoC4SGBRoChQEBYAFWgIAFAIehVAWn8fgBCvDvXNcSGVlOCUpPm2BiAuEUAB"
1129
+ "KgBCUWABEKEBUCyNosACgn4aKLR+DoAQl0e76QgwfUpwStI8rQGIywUWLWlQoAAWS6UBCATj"
1130
+ "8fBPBb0aIK2/DUCI10a66sBxpGeT9Tc0APGauNKYBQtLdwdUoAFAyz+XCvSzQKH1NwEIcXW0"
1131
+ "yw4UR3c2WX9VAxBXCzQFzi2wGFAaQgEsChDQUFyBfh6A1t8AIMQvDfXdYeGIzibrL2kA4g0C"
1132
+ "6BzhAkAvMI5r7ChNoLz7eiHoFwDS+isAhCij3XdAOIqzyfqLGoAobaUBel3hBgD4SuOUM6Ov"
1133
+ "hwT9MgCtvwRACDnQjQeAAz+brD+nAQjJQ+5eKtrhN74LM7pyS2nYgkXEjI52nQL9CkBafwGA"
1134
+ "EKeGenPOONizyfozGoA4xaIn4whzA+hj79419so7AwCoX7Cccrt+Qb8KQOvPARDihmiHzhbp"
1135
+ "bkRsTppHNABxg0BTgIqlQiwdYeYRd0rTu8axcltpQPFy90aCfgMotH4UgBA3DvftvJDiRsTm"
1136
+ "pHlYAxA3spA74NLCir2XrrEnMH1wjojS2C7z4I0E/RZQaP0pAELcNNrJs0BaGxGbk+aMBiBu"
1137
+ "CobczKeB7RHHYvKR4NyL0l3fmd+IK9BbAGj9SQBC3LxGpyeJVDYiNifNgxqAuLkNue2YuTVg"
1138
+ "7yeQVR7I/q0WnDtKY/nOiLVE0NsB0voTAIS4bbi3U8b0GxGbk+bDGoC4rVWaaMzsx96h8o2D"
1139
+ "c+eOQ9F7fyNB7wKg9ccACHH7GgOQDGZ5NlnfrwGI273knjPvnZAbTADglHOjDbnhBedASGD4"
1140
+ "HYMtCd7RhPG/D5DWDwAQ4nSsz9PEzM4m6w9oAOK0wIIpDWDFxo5OdCF3HzzbAtOvXMY1iQfn"
1141
+ "rsB0KxciLeEXcM2zWiLoDgBafxCAEHeuMgopYDZnk/X7NQBxlx1yA3bszaZ1rxORmLzP/nWO"
1142
+ "yGrB+XpROpeuyAVFgQUJ+iOg0Ppe088k7h4YhRQwg7PJ+j0agHifmfrnggoAy1HvfNumQMEW"
1143
+ "FDDxWP7pG+zrA9G7+dRxjYtWaRxdMd9qPCUzuhUo7wwYH1+cd5fRJ63fB4DEvWMDMhnSTQku"
1144
+ "AH2nBiDe36ZeePRrprLr5GJECQJftwUAdm2Wb8Rj71WCf6ZkjoCtENILuhsotL4LAIkPrjo8"
1145
+ "e0SKKcEFoO/QAMRfEhqA2FznYXanGb3rENn6NobruwwojVMtP8oTz/65rRrdkOeRfLhVgj4A"
1146
+ "kNanAZB4YK2R2jXSSgkuAH27BiDub3u/m5R+FL1cI1rfNhxdjwXPsSi9u8z1ncdi71i1a7XK"
1147
+ "rlbQ/QC0/gMAJD627pDtCKmkBBeAfpcGIP6G0ADnOuk1rgS2JETLR4Pn4Wq7y1ao1lKaWPA/"
1148
+ "8PXRao0f/WGAtL4VAIlPDI7SPjB9SnAB6Js1APEgUxrAimm5EwpPafqNJ9t3GQ+eg2F8XGkC"
1149
+ "1XKlWTH4755ulZifh/RGgR4EoPU7AZD45LrDt0VMfDZZv0UDEA8RFp7SBMLsgSiaTVln6o9m"
1150
+ "5yyP26t/3OOOJf3s5lnbEaFmO/WEQ/pOgc4AhdY3ASDxKXeQ9oLJzibrGzUA8XDbO+Gpxqbs"
1151
+ "cmb7W9+OErRGrNwVMDsIXzE475QgXL6L+gPdIuhhAFr/DgASj64+iFvBBGeT9W9qAOJfWp9m"
1152
+ "4cXMnRGLckeD5+GYPFzPXOsX9AhAWt8AgMRnx4dwS9jr2WR9SgMQn7VD7t6liJzKi87g4Km/"
1153
+ "uBIcdP2CPgOQ1qcAkPjC2DBuAXs6m6yv0wCEYo6wE446HvFAlBsLnp3yo6xfkAKgtQRA4vGN"
1154
+ "KLEqdn42WZcagHicsGDRUywKtXxDVr6t4Pk46hf0RaDQugRA4iujY7oZdqg6+g0agPhy+6gj"
1155
+ "wS3b4g6X+7G3F9y60a83U4fK/fPL3Uqx6/q95MKynkiUPhpSFMCCBH0ZgNa/CIDE19cd6FHs"
1156
+ "RHX01RqA+LofcgeDT77FPRyTrxbcBhL/bKb69fe7HHb9MSVwg/9IFB0767N2cuFE9Qv6KlBo"
1157
+ "fTUAEt/E9rBl1dGv0QDEU+2jxmJjf+PGFRg7Jg+4nKtMUK9+f4KOurSuUvLgn9c/3AB27BCh"
1158
+ "+v0H6ZwY9wGHfWe/fuNEPwVA69cCIPGtdQc9iK2pjr5cAxDfYiE3sJyyFIktY+V+7Bp6U643"
1159
+ "/HqcwzqjN+p8jlgDovVEyp3kgn/scMUbjTdgjZ4U9DRAWl8OgMRzwfGVUiqlgh852ILq6Es0"
1160
+ "APFcu0kU3nD25oc/76NvxI3GtLZH6ShBtAFe/YOv5IWUbHgPvPNhI0/q1x+L0mPvHAa2wIIN"
1161
+ "cN4t/G+AtL4EAInvrUuADqtSpyMjVx19kQYgvtdSIeBRtg9geY7+tPDy/U7ICm/+uS4nv5E9"
1162
+ "QQMN6OoJnfixGhC8kf2kQzcafNLYg4SV5oRP6napoO8ApPVFAEj8sBvlFfmAtVTHsMeojj5f"
1163
+ "AxA/bEPuXmBs+rse69i0CPyMTWDeuB5xfyOvAYHg1txoteDZfSMn/qTujQae1G5JwLcdvFH/"
1164
+ "dvPokzo3CjypoP8DCq3PB0DiJQCAllKssmats2BpSCG11gDES+ZRz0UBgE1TAlD0RncSzynv"
1165
+ "j4eyr4OWua9AeWsgVL9f7tTfVxgrt+vvDKd+/0ZOPf2VTjmLjHg93doULo/X7zjXndFJjlN/"
1166
+ "uLwL4w1pfgLQWBlr+joaQgj8uHDLqV3GouXF8n8LWMZyirSXGaN3+rgBtni1iVfA8kZ5eec+"
1167
+ "F+wymPgOyzMSvNx8zQRNYPU45c64dvVYvFmZQN2i41zgjLT/UodVztUdlngbKQqmIZx8xI/P"
1168
+ "WYs32MBNhgbEAq+cC2pPkvvt4AmSbsXtoiHjFS2Y0YkT7GDYPwRDZqQLLFoHq/OFrXJumE/b"
1169
+ "zi2YnhOsdcHc2ve0zAA3rG2uwZra2GtNFxA0hdUGfzEie303t+57pn0oYkbTdoi/g+EfsCen"
1170
+ "P5eNVI/WANZxcjamzpI9LyulZHW9u4L2C7C94loeHIKOWz+ZnF6IHUiIhXKjDlDA7VjhLLqp"
1171
+ "x2lbd0GQ+rzNHfV5uSUA6F2W2NvNQ8E/6/muPztWWVmMZSPVP9VmPKWUtuSs5O6sQx1h/dXF"
1172
+ "XLL67WVHBzw4NmbhN6Qcxy0eIAwPVS/1o+d17KFyhmSNoYrRbngLkwuDd6rQoVcvmbw8Etub"
1173
+ "JjVOfzqjUKAAiNSZmo9jYHRXocOK+Z9RyOrtQDvqi3bUzaA2zFh+Gitvv25cVMtoO46Xo10u"
1174
+ "0a6STasZDbtgWd4a3SqJdlHgTe2/RWhCBm+qadKiM0w7fcNuatc5vdHW4zYVaIr+iZxe6jvZ"
1175
+ "aaHdt6yT1d/1pDkhNlqwQlD1GQCyeudS58NrkOdIxrJwlkcZTL4FYxbb5ey8bMt1dXxYr6kx"
1176
+ "J9dZ71bxgle6IHhlpM1d/qxrvCn3I1ayKlQf2RpjOmxNdRzI6ve8SUkBAeD6EZhejjB4AjAw"
1177
+ "7bgSdCIHYioVlwowSeg1z5eK7u6OyJE36WOa4clYWHGZXHUyNiK9S0P91fZJY7Ar6hjI6g/Z"
1178
+ "WLLFIqzqsJenYVVn8u6MUGCobCoEhiq2tjL9t2jnDxXYHIiUL3wjRjtuOItsfG7Y/anu3RVp"
1179
+ "DHZLHQNZ3QmEpt3wUC2CUuEpAefZNocq1FRrCIPUJ8uh4VNiwKGJSq8zc+w2x7zJBam7d0sa"
1180
+ "g31Qx0BW7wkPai/vITEPTjtfzDnPwmMWGqqojAVp1349MGYhAbBWSc5Cu4XBRdZdhvymwp4w"
1181
+ "7fL0p/sgjcHW3ORRqPpuALK6Z+m+FZHdxK7EGMTzql46NeBuEwB34ybmJlvudtz5LZysP69n"
1182
+ "LS8Ytks76JibtN7ABWipSaT+eH+M6bA/1XEgq/viYh4JbpvItFsElSCmEEHXNbg4rp8sCLuu"
1183
+ "3ioZyxoElsvQKsmWS3X7BKQxmIw6BrJ6AIi5QRRW9YHgwhmqfszaC+BlTfyIyU/8uP5QaCUK"
1184
+ "Lz0hVg0sPdyhia2SraFum4w0BhNTx0BWfwv4YzYoFQNDFZYKrBfchiPwsbyiI2M+9WNZO8eh"
1185
+ "GcgaNKRumZg0BklQx0BWf9+vTQOqzsfMCdFXGrPBDJAzVK6MwVaIYNbAy/cM54LXSRaotyZB"
1186
+ "GoP9ucmjUPUtAGT1D0uvMPybfo7DGH9hZXlB527baWsnPR1zcp0XeP0LfC94wIjlgp2HWni5"
1187
+ "4DcnxJgOCamOA1k9Eglu7bRhLK9jrUfxvGLAoYG1ETbk0MQ0I5QK8r1+30vzHZo3pkgag3Sp"
1188
+ "YyCrx4BYXieSAo7l6AZSwLFkHUIJntX3SZwEj5UBiueCzdr0a+mSxiB16hjI6t8ibpAjFcx7"
1189
+ "iA3hgD/kyNhwLnhke8T3h3wZi+SCr0udNAbzoI6BrGpb1REaM08hYltaASVwFGI0F8wuWCWv"
1190
+ "M5YsUNfOgzQGc6KOgazOhtN3vusTyOuPDSoGEjxrJQvieyaOc2Mye6+fE2kMEoqwVoSql/+q"
1191
+ "r6y+BjIxSysM/hk/ft6bKHBUuelOASPyUunqv0Lq734gEMQ1/Ul4ddX8GNNhftTpoOrXAZDV"
1192
+ "fwEARl+R5PF2qDxwLtNc32pV7KcFnXcOnQu6ZIEx2pPw6soZk8ZgxtQxUPWVAGT1zHJaO3md"
1193
+ "LusTUwgKyVWMf7Ef8w7+cmVExtRlsyeNweypY6DqKwDI6n+W5LDevY0rAbV+jNEeXyGC9HJ+"
1194
+ "vGL4ZSi2SqqLD4Q0BgdCHQNVXwpAVv/brkHtoMJeehx6BX9Gw3FoOnenM4LlLqtaL/jCgyKN"
1195
+ "wUFRx0DVFxpDVi+2fnQb8vhv2TkCE3wBBbBXQ0fVorsf6rwDZEyHA6ROB1X/FABZveIO8JIu"
1196
+ "nr9spGLo1S3mR/s8Y56N0odMGoNDpo6Bqs8BICuyHRq4u6qdYT5yFyzHj46+5aleOXzSGBw+"
1197
+ "dQxU/QoAWV0Q8qMx8pan6+iE/SH1g2MhjcGxUMdA1T8AIKuLAdipoI4oYJke28uOv5Crnj8u"
1198
+ "0hgcF3UMVP1dY8jqZ0Aw/3KilY9mwVH0x5pA6tljZEyHY6ROB1U/C0BWV4TzOl4KuHdonjlq"
1199
+ "0hgcNXUMVP0MAFn9nKsrQYfmyUyaJTJ1llD1kwBk9Xrm2YC7Qeo/M2ksZOpYUPUTAGR1LYBu"
1200
+ "wVJnM2kCyNQJQNX/MXUTZoBi6gZkzBWZOhkbIlMnY0Nk6mRsiP8H0trOAD1A8ycAAAAASUVO"
1201
+ "RK5CYII=")
1202
+
1203
+
1204
+ def rad2deg(x):
1205
+ """
1206
+ Transforms radians into degrees.
1207
+
1208
+ :param `x`: a float representing an angle in radians.
1209
+ """
1210
+
1211
+ return 180.0*x/pi
1212
+
1213
+
1214
+ def deg2rad(x):
1215
+ """
1216
+ Transforms degrees into radians.
1217
+
1218
+ :param `x`: a float representing an angle in degrees.
1219
+ """
1220
+
1221
+ return x*pi/180.0
1222
+
1223
+
1224
+ def toscale(x):
1225
+ """
1226
+ Normalize a value as a function of the radius.
1227
+
1228
+ :param `x`: a float value to normalize
1229
+ """
1230
+
1231
+ return x*RADIUS/255.0
1232
+
1233
+
1234
+ def scaletomax(x):
1235
+ """
1236
+ Normalize a value as a function of the radius.
1237
+
1238
+ :param `x`: a float value to normalize
1239
+ """
1240
+
1241
+ return x*255.0/RADIUS
1242
+
1243
+
1244
+ def rgb2html(colour):
1245
+ """
1246
+ Transforms a RGB triplet into an html hex string.
1247
+
1248
+ :param `colour`: a tuple of red, green, blue integers.
1249
+ """
1250
+
1251
+ hexColour = "#%02x%02x%02x"%(colour.r, colour.g, colour.b)
1252
+ return hexColour.upper()
1253
+
1254
+
1255
+ def Slope(pt1, pt2):
1256
+ """
1257
+ Calculates the slope of the line connecting 2 points.
1258
+
1259
+ :param `pt1`: an instance of :class:`wx.Point`;
1260
+ :param `pt2`: another instance of :class:`wx.Point`.
1261
+ """
1262
+
1263
+ y = float(pt2.y - pt1.y)
1264
+ x = float(pt2.x - pt1.x)
1265
+
1266
+ if x:
1267
+ return y/x
1268
+ else:
1269
+ return None
1270
+
1271
+
1272
+ def Intersection(line1, line2):
1273
+ """
1274
+ Calculates the intersection point between 2 lines.
1275
+
1276
+ :param `line1`: an instance of :class:`LineDescription`;
1277
+ :param `line2`: another instance of :class:`LineDescription`.
1278
+ """
1279
+
1280
+ if line1.slope == line2.slope:
1281
+
1282
+ # Parallel lines, no intersection
1283
+ return wx.Point(0, 0)
1284
+
1285
+ elif line1.slope is None:
1286
+
1287
+ # First Line is vertical, eqn is x=0
1288
+ # Put x = 0 in second line eqn to get y
1289
+ x = line1.x
1290
+ y = line2.slope*x + line2.c
1291
+
1292
+ elif line2.slope is None:
1293
+
1294
+ # second line is vertical Equation of line is x=0
1295
+ # Put x = 0 in first line eqn to get y
1296
+ x = line2.x
1297
+ y = line1.slope*line2.x + line1.c
1298
+
1299
+ else:
1300
+
1301
+ y = ((line1.c*line2.slope) - (line2.c*line1.slope))/(line2.slope - line1.slope)
1302
+ x = (y - line1.c)/line1.slope
1303
+
1304
+
1305
+ return wx.Point(int(x), int(y))
1306
+
1307
+
1308
+ def FindC(line):
1309
+ """ Internal function. """
1310
+
1311
+ if line.slope is None:
1312
+ c = line.y
1313
+ else:
1314
+ c = line.y - line.slope*line.x
1315
+
1316
+ return c
1317
+
1318
+
1319
+ def PointOnLine(pt1, pt2, length, maxLen):
1320
+ """ Internal function. """
1321
+
1322
+ a = float(length)
1323
+
1324
+ if pt2.x != pt1.x:
1325
+
1326
+ m = float((pt2.y - pt1.y))/(pt2.x - pt1.x)
1327
+ m2 = m*m
1328
+ a2 = a*a
1329
+ c = pt1.y - m*pt1.x
1330
+ c2 = c*c
1331
+
1332
+ A = 1.0
1333
+
1334
+ x = pt1.x
1335
+
1336
+ B = 2.0 * pt1.x
1337
+
1338
+ x *= x
1339
+ C = x - a2/(m2 + 1)
1340
+
1341
+ x = (B + sqrt(B*B - (4.0*A*C)))/(2.0*A)
1342
+ y = m*x + c
1343
+ pt = wx.Point(int(x), int(y))
1344
+
1345
+ if Distance(pt, pt1) > maxLen or Distance(pt, pt2) > maxLen:
1346
+
1347
+ x = (B - sqrt(B*B - (4.0*A*C)))/(2.0*A)
1348
+ y = m*x + c
1349
+ pt = wx.Point(int(x), int(y))
1350
+
1351
+ else:
1352
+
1353
+ a2 = a*a
1354
+ y = sqrt(a2)
1355
+ x = 0.0
1356
+ pt = wx.Point(int(x), int(y))
1357
+ pt.x += pt1.x
1358
+ pt.y += pt1.y
1359
+
1360
+ if Distance(pt, pt1) > maxLen or Distance(pt, pt2) > maxLen:
1361
+
1362
+ y = -1.0*y
1363
+ pt = wx.Point(int(x), int(y))
1364
+ pt.x += pt1.x
1365
+ pt.y += pt1.y
1366
+
1367
+ return pt
1368
+
1369
+
1370
+ def Distance(pt1, pt2):
1371
+ """
1372
+ Returns the distance between 2 points.
1373
+
1374
+ :param `pt1`: an instance of :class:`wx.Point`;
1375
+ :param `pt2`: another instance of :class:`wx.Point`.
1376
+ """
1377
+
1378
+ distance = sqrt((pt1.x - pt2.x)**2.0 + (pt1.y - pt2.y)**2.0)
1379
+ return int(distance)
1380
+
1381
+
1382
+ def AngleFromPoint(pt, center):
1383
+ """
1384
+ Returns the angle between the x-axis and the line connecting the center and
1385
+ the point `pt`.
1386
+
1387
+ :param `pt`: an instance of :class:`wx.Point`;
1388
+ :param `center`: a float value representing the center.
1389
+ """
1390
+
1391
+ y = -1*(pt.y - center.y)
1392
+ x = pt.x - center.x
1393
+ if x == 0 and y == 0:
1394
+
1395
+ return 0.0
1396
+
1397
+ else:
1398
+
1399
+ return atan2(y, x)
1400
+
1401
+
1402
+ def PtFromAngle(angle, sat, center):
1403
+ """
1404
+ Given the angle with respect to the x-axis, returns the point based on
1405
+ the saturation value.
1406
+
1407
+ :param `angle`: a float representing an angle;
1408
+ :param `sat`: a float representing the colour saturation value;
1409
+ :param `center`: a float value representing the center.
1410
+ """
1411
+
1412
+ angle = deg2rad(angle)
1413
+ sat = toscale(sat)
1414
+
1415
+ x = sat*cos(angle)
1416
+ y = sat*sin(angle)
1417
+
1418
+ pt = wx.Point(int(x), -int(y))
1419
+ pt.x += center.x
1420
+ pt.y += center.y
1421
+
1422
+ return pt
1423
+
1424
+
1425
+ def RestoreOldDC(dc, oldPen, oldBrush, oldMode):
1426
+ """
1427
+ Restores the old settings for a :class:`wx.DC`.
1428
+
1429
+ :param `dc`: an instance of :class:`wx.DC`;
1430
+ :param `oldPen`: an instance of :class:`wx.Pen`;
1431
+ :param `oldBrush`: an instance of :class:`wx.Brush`;
1432
+ :param `oldMode`: the :class:`wx.DC` drawing mode bit.
1433
+ """
1434
+
1435
+ dc.SetPen(oldPen)
1436
+ dc.SetBrush(oldBrush)
1437
+ dc.SetLogicalFunction(oldMode)
1438
+
1439
+
1440
+ def DrawCheckerBoard(dc, rect, checkColour, box=5):
1441
+ """
1442
+ Draws a checkerboard on a :class:`wx.DC`.
1443
+
1444
+ :param `dc`: an instance of :class:`wx.DC`;
1445
+ :param `rect`: the client rectangle on which to draw the checkerboard;
1446
+ :param `checkColour`: the colour used for the dark checkerboards;
1447
+ :param `box`: the checkerboards box sizes.
1448
+
1449
+ :note: Used for the Alpha channel control and the colour panels.
1450
+ """
1451
+
1452
+ y = rect.y
1453
+ checkPen = wx.Pen(checkColour)
1454
+ checkBrush = wx.Brush(checkColour)
1455
+
1456
+ dc.SetPen(checkPen)
1457
+ dc.SetBrush(checkBrush)
1458
+ dc.SetClippingRegion(rect)
1459
+
1460
+ while y < rect.height:
1461
+ x = box*((y//box)%2) + 2
1462
+ while x < rect.width:
1463
+ dc.DrawRectangle(x, y, box, box)
1464
+ x += box*2
1465
+ y += box
1466
+
1467
+
1468
+
1469
+ class Colour(wx.Colour):
1470
+ """
1471
+ This is a subclass of :class:`wx.Colour`, which adds Hue, Saturation and Brightness
1472
+ capability to the base class. It contains also methods to convert RGB triplets
1473
+ into HSB triplets and vice-versa.
1474
+ """
1475
+
1476
+ def __init__(self, colour):
1477
+ """
1478
+ Default class constructor.
1479
+
1480
+ :param `colour`: a standard :class:`wx.Colour`.
1481
+ """
1482
+
1483
+ wx.Colour.__init__(self)
1484
+
1485
+ self.r = colour.Red()
1486
+ self.g = colour.Green()
1487
+ self.b = colour.Blue()
1488
+ self._alpha = colour.Alpha()
1489
+
1490
+ self.ToHSV()
1491
+
1492
+
1493
+ def ToRGB(self):
1494
+ """ Converts a HSV triplet into a RGB triplet. """
1495
+
1496
+ maxVal = self.v
1497
+ delta = (maxVal*self.s)/255.0
1498
+ minVal = maxVal - delta
1499
+
1500
+ hue = float(self.h)
1501
+
1502
+ if self.h > 300 or self.h <= 60:
1503
+
1504
+ self.r = maxVal
1505
+
1506
+ if self.h > 300:
1507
+
1508
+ self.g = int(minVal)
1509
+ hue = (hue - 360.0)/60.0
1510
+ self.b = int(-(hue*delta - minVal))
1511
+
1512
+ else:
1513
+
1514
+ self.b = int(minVal)
1515
+ hue = hue/60.0
1516
+ self.g = int(hue*delta + minVal)
1517
+
1518
+ elif self.h > 60 and self.h < 180:
1519
+
1520
+ self.g = int(maxVal)
1521
+
1522
+ if self.h < 120:
1523
+
1524
+ self.b = int(minVal)
1525
+ hue = (hue/60.0 - 2.0)*delta
1526
+ self.r = int(minVal - hue)
1527
+
1528
+ else:
1529
+
1530
+ self.r = int(minVal)
1531
+ hue = (hue/60.0 - 2.0)*delta
1532
+ self.b = int(minVal + hue)
1533
+
1534
+
1535
+ else:
1536
+
1537
+ self.b = int(maxVal)
1538
+
1539
+ if self.h < 240:
1540
+
1541
+ self.r = int(minVal)
1542
+ hue = (hue/60.0 - 4.0)*delta
1543
+ self.g = int(minVal - hue)
1544
+
1545
+ else:
1546
+
1547
+ self.g = int(minVal)
1548
+ hue = (hue/60.0 - 4.0)*delta
1549
+ self.r = int(minVal + hue)
1550
+
1551
+
1552
+ def ToHSV(self):
1553
+ """ Converts a RGB triplet into a HSV triplet. """
1554
+
1555
+ minVal = float(min(self.r, min(self.g, self.b)))
1556
+ maxVal = float(max(self.r, max(self.g, self.b)))
1557
+ delta = maxVal - minVal
1558
+
1559
+ self.v = int(maxVal)
1560
+
1561
+ if abs(delta) < 1e-6:
1562
+
1563
+ self.h = self.s = 0
1564
+
1565
+ else:
1566
+
1567
+ temp = delta/maxVal
1568
+ self.s = int(temp*255.0)
1569
+
1570
+ if self.r == int(maxVal):
1571
+
1572
+ temp = float(self.g-self.b)/delta
1573
+
1574
+ elif self.g == int(maxVal):
1575
+
1576
+ temp = 2.0 + (float(self.b-self.r)/delta)
1577
+
1578
+ else:
1579
+
1580
+ temp = 4.0 + (float(self.r-self.g)/delta)
1581
+
1582
+ temp *= 60
1583
+ if temp < 0:
1584
+
1585
+ temp += 360
1586
+
1587
+ elif temp >= 360.0:
1588
+
1589
+ temp = 0
1590
+
1591
+ self.h = int(temp)
1592
+
1593
+
1594
+ def GetPyColour(self):
1595
+ """ Returns the wxPython :class:`wx.Colour` associated with this instance. """
1596
+
1597
+ return wx.Colour(self.r, self.g, self.b, self._alpha)
1598
+
1599
+
1600
+
1601
+ class LineDescription(object):
1602
+ """ Simple class to store description and constants for a line in 2D space. """
1603
+
1604
+ def __init__(self, x=0, y=0, slope=None, c=None):
1605
+ """
1606
+ Default class constructor.
1607
+
1608
+ Used internally. Do not call it in your code!
1609
+
1610
+ :param `x`: the x coordinate of the first point;
1611
+ :param `y`: the y coordinate of the first point;
1612
+ :param `slope`: the line's slope;
1613
+ :param `c`: a floating point constant.
1614
+ """
1615
+
1616
+ self.x = x
1617
+ self.y = y
1618
+ self.slope = slope
1619
+ self.c = c
1620
+
1621
+
1622
+ class BasePyControl(wx.Control):
1623
+ """
1624
+ Base class used to hold common code for the HSB colour wheel and the RGB
1625
+ colour cube.
1626
+ """
1627
+
1628
+ def __init__(self, parent, bitmap=None):
1629
+ """
1630
+ Default class constructor.
1631
+ Used internally. Do not call it in your code!
1632
+
1633
+ :param `parent`: the control parent;
1634
+ :param `bitmap`: the background bitmap for this custom control.
1635
+ """
1636
+
1637
+ wx.Control.__init__(self, parent, style=wx.NO_BORDER)
1638
+ self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
1639
+
1640
+ if not self.IsDoubleBuffered():
1641
+ self.SetDoubleBuffered(True)
1642
+
1643
+ self._bitmap = bitmap
1644
+ mask = wx.Mask(self._bitmap, wx.LIGHT_GREY)
1645
+ self._bitmap.SetMask(mask)
1646
+
1647
+ self._mainDialog = wx.GetTopLevelParent(self)
1648
+
1649
+ self.Bind(wx.EVT_SIZE, self.OnSize)
1650
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
1651
+ self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
1652
+ self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
1653
+ self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
1654
+ self.Bind(wx.EVT_MOTION, self.OnMotion)
1655
+
1656
+
1657
+ def OnPaint(self, event):
1658
+ """
1659
+ Handles the ``wx.EVT_PAINT`` for :class:`BasePyControl`.
1660
+
1661
+ :param `event`: a :class:`PaintEvent` event to be processed.
1662
+ """
1663
+
1664
+ dc = wx.AutoBufferedPaintDC(self)
1665
+ dc.SetBackground(wx.Brush(self.GetParent().GetBackgroundColour()))
1666
+
1667
+ dc.Clear()
1668
+ dc.DrawBitmap(self._bitmap, 0, 0, True)
1669
+
1670
+ if self._mainDialog._initOver:
1671
+ self.DrawMarkers(dc)
1672
+
1673
+
1674
+ def OnEraseBackground(self, event):
1675
+ """
1676
+ Handles the ``wx.EVT_ERASE_BACKGROUND`` for :class:`BasePyControl`.
1677
+
1678
+ :param `event`: a :class:`EraseEvent` event to be processed.
1679
+
1680
+ :note: This is intentionally empty to reduce flicker.
1681
+ """
1682
+
1683
+ pass
1684
+
1685
+
1686
+ def DrawMarkers(self, dc=None):
1687
+ """
1688
+ Draws the markers on top of the background bitmap.
1689
+
1690
+ :param `dc`: an instance of :class:`wx.DC`.
1691
+
1692
+ :note: This method must be overridden in derived classes.
1693
+ """
1694
+
1695
+ pass
1696
+
1697
+
1698
+ def DrawLines(self, dc):
1699
+ """
1700
+ Draws the lines connecting the markers on top of the background bitmap.
1701
+
1702
+ :param `dc`: an instance of :class:`wx.DC`.
1703
+
1704
+ :note: This method must be overridden in derived classes.
1705
+ """
1706
+
1707
+ pass
1708
+
1709
+
1710
+ def AcceptsFocusFromKeyboard(self):
1711
+ """
1712
+ Can this window be given focus by keyboard navigation? If not, the
1713
+ only way to give it focus (provided it accepts it at all) is to click
1714
+ it.
1715
+
1716
+ :note: This method always returns ``False`` as we do not accept focus from
1717
+ the keyboard.
1718
+
1719
+ :note: Overridden from :class:`wx.Control`.
1720
+ """
1721
+
1722
+ return False
1723
+
1724
+
1725
+ def AcceptsFocus(self):
1726
+ """
1727
+ Can this window be given focus by mouse click?
1728
+
1729
+ :note: This method always returns ``False`` as we do not accept focus from
1730
+ mouse click.
1731
+
1732
+ :note: Overridden from :class:`wx.Control`.
1733
+ """
1734
+
1735
+ return False
1736
+
1737
+
1738
+ def OnLeftDown(self, event):
1739
+ """
1740
+ Handles the ``wx.EVT_LEFT_DOWN`` for :class:`BasePyControl`.
1741
+
1742
+ :param `event`: a :class:`MouseEvent` event to be processed.
1743
+
1744
+ :note: This method must be overridden in derived classes.
1745
+ """
1746
+
1747
+ pass
1748
+
1749
+
1750
+ def OnLeftUp(self, event):
1751
+ """
1752
+ Handles the ``wx.EVT_LEFT_UP`` for :class:`BasePyControl`.
1753
+
1754
+ :param `event`: a :class:`MouseEvent` event to be processed.
1755
+
1756
+ :note: This method must be overridden in derived classes.
1757
+ """
1758
+
1759
+ pass
1760
+
1761
+
1762
+ def OnMotion(self, event):
1763
+ """
1764
+ Handles the ``wx.EVT_MOTION`` for :class:`BasePyControl`.
1765
+
1766
+ :param `event`: a :class:`MouseEvent` event to be processed.
1767
+
1768
+ :note: This method must be overridden in derived classes.
1769
+ """
1770
+
1771
+ pass
1772
+
1773
+
1774
+ def OnSize(self, event):
1775
+ """
1776
+ Handles the ``wx.EVT_SIZE`` for :class:`BasePyControl`.
1777
+
1778
+ :param `event`: a :class:`wx.SizeEvent` event to be processed.
1779
+ """
1780
+
1781
+ self.Refresh()
1782
+
1783
+
1784
+ def DoGetBestSize(self):
1785
+ """
1786
+ Overridden base class virtual. Determines the best size of the
1787
+ control based on the bitmap size.
1788
+
1789
+ :note: Overridden from :class:`wx.Control`.
1790
+ """
1791
+
1792
+ return wx.Size(self._bitmap.GetWidth(), self._bitmap.GetHeight())
1793
+
1794
+
1795
+
1796
+ class RGBCube(BasePyControl):
1797
+ """
1798
+ Implements the drawing, mouse handling and sizing routines for the RGB
1799
+ cube colour.
1800
+ """
1801
+
1802
+ def __init__(self, parent):
1803
+ """
1804
+ Default class constructor.
1805
+ Used internally. Do not call it in your code!
1806
+
1807
+ :param `parent`: the control parent window.
1808
+ """
1809
+
1810
+ BasePyControl.__init__(self, parent, bitmap=RGBCubeImage.GetBitmap())
1811
+ self._index = -1
1812
+ self._mouseIn = False
1813
+
1814
+
1815
+ def DrawMarkers(self, dc=None):
1816
+ """
1817
+ Draws the markers on top of the background bitmap.
1818
+
1819
+ :param `dc`: an instance of :class:`wx.DC`.
1820
+ """
1821
+
1822
+ if dc is None:
1823
+ dc = wx.ClientDC(self)
1824
+
1825
+ oldPen, oldBrush, oldMode = dc.GetPen(), dc.GetBrush(), dc.GetLogicalFunction()
1826
+ dc.SetPen(wx.WHITE_PEN)
1827
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
1828
+ dc.SetLogicalFunction(wx.XOR)
1829
+
1830
+ rects = []
1831
+ blueLen = self._mainDialog._blueLen
1832
+ greenLen = self._mainDialog._greenLen
1833
+ redLen = self._mainDialog._redLen
1834
+ colour = self._mainDialog._colour
1835
+
1836
+ pt = [wx.Point() for i in range(3)]
1837
+ pt[0] = PointOnLine(Vertex, Top, (colour.r*redLen)/255.0, redLen)
1838
+ pt[1] = PointOnLine(Vertex, Left, (colour.g*greenLen)/255.0, greenLen)
1839
+ pt[2] = PointOnLine(Vertex, Right, (colour.b*blueLen)/255.0, blueLen)
1840
+
1841
+ for i in range(3):
1842
+ rect = wx.Rect(pt[i].x - RECT_WIDTH, pt[i].y - RECT_WIDTH, 2*RECT_WIDTH, 2*RECT_WIDTH)
1843
+ rects.append(rect)
1844
+ dc.DrawRectangle(rect)
1845
+
1846
+ self.DrawLines(dc)
1847
+ RestoreOldDC(dc, oldPen, oldBrush, oldMode)
1848
+
1849
+ self._rects = rects
1850
+
1851
+
1852
+ def DrawLines(self, dc):
1853
+ """
1854
+ Draws the lines connecting the markers on top of the background bitmap.
1855
+
1856
+ :param `dc`: an instance of :class:`wx.DC`.
1857
+ """
1858
+
1859
+ cuboid = self._mainDialog._cuboid
1860
+
1861
+ dc.DrawLine(cuboid[1], cuboid[2])
1862
+ dc.DrawLine(cuboid[2], cuboid[3])
1863
+ dc.DrawLine(cuboid[3], cuboid[4])
1864
+ dc.DrawLine(cuboid[4], cuboid[5])
1865
+ dc.DrawLine(cuboid[5], cuboid[2])
1866
+
1867
+ dc.DrawLine(cuboid[5], cuboid[6])
1868
+ dc.DrawLine(cuboid[6], cuboid[7])
1869
+ dc.DrawLine(cuboid[7], cuboid[4])
1870
+
1871
+ dc.DrawLine(cuboid[1], cuboid[6])
1872
+
1873
+
1874
+ def OnLeftDown(self, event):
1875
+ """
1876
+ Handles the ``wx.EVT_LEFT_DOWN`` for :class:`RGBCube`.
1877
+
1878
+ :param `event`: a :class:`MouseEvent` event to be processed.
1879
+ """
1880
+
1881
+ point = wx.Point(event.GetX(), event.GetY())
1882
+ self._mouseIn = False
1883
+
1884
+ if self._rects[RED].Contains(point):
1885
+ self.CaptureMouse()
1886
+ self._mouseIn = True
1887
+ self._index = RED
1888
+
1889
+ elif self._rects[GREEN].Contains(point):
1890
+ self.CaptureMouse()
1891
+ self._mouseIn = True
1892
+ self._index = GREEN
1893
+
1894
+ elif self._rects[BLUE].Contains(point):
1895
+ self.CaptureMouse()
1896
+ self._mouseIn = True
1897
+ self._index = BLUE
1898
+
1899
+
1900
+ def OnLeftUp(self, event):
1901
+ """
1902
+ Handles the ``wx.EVT_LEFT_UP`` for :class:`RGBCube`.
1903
+
1904
+ :param `event`: a :class:`MouseEvent` event to be processed.
1905
+ """
1906
+
1907
+ if self.GetCapture():
1908
+ self.ReleaseMouse()
1909
+ self._mouseIn = False
1910
+
1911
+
1912
+ def OnMotion(self, event):
1913
+ """
1914
+ Handles the ``wx.EVT_MOTION`` for :class:`RGBCube`.
1915
+
1916
+ :param `event`: a :class:`MouseEvent` event to be processed.
1917
+ """
1918
+
1919
+ point = wx.Point(event.GetX(), event.GetY())
1920
+
1921
+ if not (self.GetCapture() and self._mouseIn):
1922
+ event.Skip()
1923
+ return
1924
+
1925
+ bChange = False
1926
+ mainDialog = self._mainDialog
1927
+ colour = mainDialog._colour
1928
+ redLen, greenLen, blueLen = mainDialog._redLen, mainDialog._greenLen, mainDialog._blueLen
1929
+
1930
+ dc = wx.ClientDC(self)
1931
+ self.DrawMarkers(dc)
1932
+
1933
+ if self._index == RED:
1934
+
1935
+ if point.y > Vertex.y:
1936
+ point.y = Vertex.y
1937
+
1938
+ point.x = Vertex.x
1939
+ val = Distance(point, Vertex)
1940
+ if val > redLen:
1941
+ val = redLen
1942
+
1943
+ val = (float(val)/redLen)*255.0
1944
+ colour.r = int(val)
1945
+
1946
+ pt = PointOnLine(Vertex, Top, (colour.r*redLen)/255.0, redLen)
1947
+ self._rects[RED] = wx.Rect(pt.x - RECT_WIDTH, pt.y - RECT_WIDTH,
1948
+ 2*RECT_WIDTH, 2*RECT_WIDTH)
1949
+
1950
+ bChange = True
1951
+
1952
+ elif self._index == GREEN:
1953
+
1954
+ if point.x > Vertex.x:
1955
+ point.x = Vertex.x
1956
+
1957
+ point.y = self._rects[GREEN].GetTop() + RECT_WIDTH
1958
+ val = Distance(point, Vertex)
1959
+ if val > greenLen:
1960
+ val = greenLen
1961
+
1962
+ val = (float(val)/greenLen)*255.0
1963
+ colour.g = int(val)
1964
+
1965
+ pt = PointOnLine(Vertex, Left, (colour.g*greenLen)/255.0, greenLen)
1966
+ self._rects[GREEN] = wx.Rect(pt.x - RECT_WIDTH, pt.y - RECT_WIDTH,
1967
+ 2*RECT_WIDTH, 2*RECT_WIDTH)
1968
+
1969
+ bChange = True
1970
+
1971
+ elif self._index == BLUE:
1972
+
1973
+ if point.x < Vertex.x:
1974
+ point.x = Vertex.x
1975
+
1976
+ point.y = self._rects[BLUE].GetTop() + RECT_WIDTH
1977
+ val = Distance(point, Vertex)
1978
+ if val > blueLen:
1979
+ val = blueLen
1980
+
1981
+ val = (float(val)/blueLen)*255.0
1982
+ colour.b = int(val)
1983
+
1984
+ pt = PointOnLine(Vertex, Right, (colour.b*blueLen)/255.0, blueLen)
1985
+ self._rects[BLUE] = wx.Rect(pt.x - RECT_WIDTH, pt.y - RECT_WIDTH,
1986
+ 2*RECT_WIDTH, 2*RECT_WIDTH)
1987
+
1988
+ bChange = True
1989
+
1990
+ if bChange:
1991
+
1992
+ mainDialog.CalcCuboid()
1993
+ self.DrawMarkers(dc)
1994
+
1995
+ colour.ToHSV()
1996
+ mainDialog.SetSpinVals()
1997
+ mainDialog.CalcRects()
1998
+
1999
+ mainDialog.DrawHSB()
2000
+ mainDialog.DrawBright()
2001
+ mainDialog.DrawAlpha()
2002
+
2003
+
2004
+ class HSVWheel(BasePyControl):
2005
+ """
2006
+ Implements the drawing, mouse handling and sizing routines for the HSV
2007
+ colour wheel.
2008
+ """
2009
+
2010
+ def __init__(self, parent):
2011
+ """
2012
+ Default class constructor.
2013
+ Used internally. Do not call it in your code!
2014
+
2015
+ :param `parent`: the control parent window.
2016
+ """
2017
+
2018
+ BasePyControl.__init__(self, parent, bitmap=HSVWheelImage.GetBitmap())
2019
+ self._mouseIn = False
2020
+
2021
+
2022
+ def DrawMarkers(self, dc=None):
2023
+ """
2024
+ Draws the markers on top of the background bitmap.
2025
+
2026
+ :param `dc`: an instance of :class:`wx.DC`.
2027
+ """
2028
+
2029
+ if dc is None:
2030
+ dc = wx.ClientDC(self)
2031
+
2032
+ oldPen, oldBrush, oldMode = dc.GetPen(), dc.GetBrush(), dc.GetLogicalFunction()
2033
+ dc.SetPen(wx.WHITE_PEN)
2034
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
2035
+ dc.SetLogicalFunction(wx.XOR)
2036
+
2037
+ dc.DrawRectangle(self._mainDialog._currentRect)
2038
+ RestoreOldDC(dc, oldPen, oldBrush, oldMode)
2039
+
2040
+
2041
+ def OnLeftDown(self, event):
2042
+ """
2043
+ Handles the ``wx.EVT_LEFT_DOWN`` for :class:`HSVWheel`.
2044
+
2045
+ :param `event`: a :class:`MouseEvent` event to be processed.
2046
+ """
2047
+
2048
+ point = wx.Point(event.GetX(), event.GetY())
2049
+ self._mouseIn = False
2050
+
2051
+ if self.InCircle(point):
2052
+ self._mouseIn = True
2053
+
2054
+ if self._mouseIn:
2055
+ self.CaptureMouse()
2056
+ self.TrackPoint(point)
2057
+
2058
+
2059
+ def OnLeftUp(self, event):
2060
+ """
2061
+ Handles the ``wx.EVT_LEFT_UP`` for :class:`HSVWheel`.
2062
+
2063
+ :param `event`: a :class:`MouseEvent` event to be processed.
2064
+ """
2065
+
2066
+ if self.GetCapture():
2067
+ self.ReleaseMouse()
2068
+ self._mouseIn = False
2069
+
2070
+
2071
+ def OnMotion(self, event):
2072
+ """
2073
+ Handles the ``wx.EVT_MOTION`` for :class:`HSVWheel`.
2074
+
2075
+ :param `event`: a :class:`MouseEvent` event to be processed.
2076
+ """
2077
+
2078
+ point = wx.Point(event.GetX(), event.GetY())
2079
+
2080
+ if self.GetCapture() and self._mouseIn:
2081
+ self.TrackPoint(point)
2082
+
2083
+
2084
+ def InCircle(self, pt):
2085
+ """
2086
+ Returns whether a point is inside the HSV wheel or not.
2087
+
2088
+ :param `pt`: an instance of :class:`wx.Point`.
2089
+ """
2090
+
2091
+ return Distance(pt, self._mainDialog._centre) <= RADIUS
2092
+
2093
+
2094
+ def TrackPoint(self, pt):
2095
+ """
2096
+ Track a mouse event inside the HSV colour wheel.
2097
+
2098
+ :param `pt`: an instance of :class:`wx.Point`.
2099
+ """
2100
+
2101
+ if not self._mouseIn:
2102
+ return
2103
+
2104
+ dc = wx.ClientDC(self)
2105
+ self.DrawMarkers(dc)
2106
+ mainDialog = self._mainDialog
2107
+ colour = mainDialog._colour
2108
+
2109
+ colour.h = int(rad2deg(AngleFromPoint(pt, mainDialog._centre)))
2110
+ if colour.h < 0:
2111
+ colour.h += 360
2112
+
2113
+ colour.s = int(scaletomax(Distance(pt, mainDialog._centre)))
2114
+ if colour.s > 255:
2115
+ colour.s = 255
2116
+
2117
+ mainDialog.CalcRects()
2118
+ self.DrawMarkers(dc)
2119
+ colour.ToRGB()
2120
+ mainDialog.SetSpinVals()
2121
+
2122
+ mainDialog.CalcCuboid()
2123
+ mainDialog.DrawRGB()
2124
+ mainDialog.DrawBright()
2125
+ mainDialog.DrawAlpha()
2126
+
2127
+
2128
+ class BaseLineCtrl(wx.Control):
2129
+ """
2130
+ Base class used to hold common code for the Alpha channel control and the
2131
+ brightness palette control.
2132
+ """
2133
+
2134
+ def __init__(self, parent):
2135
+ """
2136
+ Default class constructor.
2137
+ Used internally. Do not call it in your code!
2138
+
2139
+ :param `parent`: the control parent window.
2140
+ """
2141
+
2142
+ wx.Control.__init__(self, parent, size=(20, 200), style=wx.NO_BORDER)
2143
+ self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
2144
+
2145
+ self._mainDialog = wx.GetTopLevelParent(self)
2146
+
2147
+ self.Bind(wx.EVT_SIZE, self.OnSize)
2148
+ self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
2149
+ self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
2150
+ self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
2151
+ self.Bind(wx.EVT_MOTION, self.OnMotion)
2152
+
2153
+
2154
+ def OnEraseBackground(self, event):
2155
+ """
2156
+ Handles the ``wx.EVT_ERASE_BACKGROUND`` for :class:`BaseLineCtrl`.
2157
+
2158
+ :param `event`: a :class:`EraseEvent` event to be processed.
2159
+
2160
+ :note: This is intentionally empty to reduce flicker.
2161
+ """
2162
+
2163
+ pass
2164
+
2165
+
2166
+ def OnLeftDown(self, event):
2167
+ """
2168
+ Handles the ``wx.EVT_LEFT_DOWN`` for :class:`BaseLineCtrl`.
2169
+
2170
+ :param `event`: a :class:`MouseEvent` event to be processed.
2171
+ """
2172
+
2173
+ point = wx.Point(event.GetX(), event.GetY())
2174
+ theRect = self.GetClientRect()
2175
+
2176
+ if not theRect.Contains(point):
2177
+ event.Skip()
2178
+ return
2179
+
2180
+ self.CaptureMouse()
2181
+ self.TrackPoint(point)
2182
+
2183
+
2184
+ def OnLeftUp(self, event):
2185
+ """
2186
+ Handles the ``wx.EVT_LEFT_UP`` for :class:`BaseLineCtrl`.
2187
+
2188
+ :param `event`: a :class:`MouseEvent` event to be processed.
2189
+ """
2190
+
2191
+ if self.GetCapture():
2192
+ self.ReleaseMouse()
2193
+
2194
+
2195
+ def OnMotion(self, event):
2196
+ """
2197
+ Handles the ``wx.EVT_MOTION`` for :class:`BaseLineCtrl`.
2198
+
2199
+ :param `event`: a :class:`MouseEvent` event to be processed.
2200
+ """
2201
+
2202
+ point = wx.Point(event.GetX(), event.GetY())
2203
+
2204
+ if self.GetCapture():
2205
+ self.TrackPoint(point)
2206
+
2207
+
2208
+ def OnSize(self, event):
2209
+ """
2210
+ Handles the ``wx.EVT_SIZE`` for :class:`BaseLineCtrl`.
2211
+
2212
+ :param `event`: a :class:`wx.SizeEvent` event to be processed.
2213
+ """
2214
+
2215
+ self.Refresh()
2216
+
2217
+
2218
+ def DoGetBestSize(self):
2219
+ """
2220
+ Overridden base class virtual. Determines the best size of the control.
2221
+
2222
+ :note: Overridden from :class:`wx.Control`.
2223
+ """
2224
+
2225
+ return wx.Size(24, 208)
2226
+
2227
+
2228
+ def BuildRect(self):
2229
+ """ Internal method. """
2230
+
2231
+ brightRect = wx.Rect(*self.GetClientRect())
2232
+ brightRect.x += 2
2233
+ brightRect.y += 6
2234
+ brightRect.width -= 4
2235
+ brightRect.height -= 8
2236
+
2237
+ return brightRect
2238
+
2239
+
2240
+ def AcceptsFocusFromKeyboard(self):
2241
+ """
2242
+ Can this window be given focus by keyboard navigation? If not, the
2243
+ only way to give it focus (provided it accepts it at all) is to click
2244
+ it.
2245
+
2246
+ :note: This method always returns ``False`` as we do not accept focus from
2247
+ the keyboard.
2248
+
2249
+ :note: Overridden from :class:`wx.Control`.
2250
+ """
2251
+
2252
+ return False
2253
+
2254
+
2255
+ def AcceptsFocus(self):
2256
+ """
2257
+ Can this window be given focus by mouse click?
2258
+
2259
+ :note: This method always returns ``False`` as we do not accept focus from
2260
+ mouse click.
2261
+
2262
+ :note: Overridden from :class:`wx.Control`.
2263
+ """
2264
+
2265
+ return False
2266
+
2267
+
2268
+
2269
+ class BrightCtrl(BaseLineCtrl):
2270
+ """
2271
+ Implements the drawing, mouse handling and sizing routines for the brightness
2272
+ palette control.
2273
+ """
2274
+
2275
+ def __init__(self, parent):
2276
+ """
2277
+ Default class constructor.
2278
+ Used internally. Do not call it in your code!
2279
+
2280
+ :param `parent`: the control parent window.
2281
+ """
2282
+
2283
+ BaseLineCtrl.__init__(self, parent)
2284
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
2285
+
2286
+
2287
+ def OnPaint(self, event):
2288
+ """
2289
+ Handles the ``wx.EVT_PAINT`` for :class:`BrightCtrl`.
2290
+
2291
+ :param `event`: a :class:`PaintEvent` event to be processed.
2292
+ """
2293
+
2294
+ dc = wx.AutoBufferedPaintDC(self)
2295
+ dc.SetBackground(wx.Brush(self.GetParent().GetBackgroundColour()))
2296
+ dc.Clear()
2297
+
2298
+ colour = self._mainDialog._colour.GetPyColour()
2299
+ brightRect = self.BuildRect()
2300
+
2301
+ target_red = colour.Red()
2302
+ target_green = colour.Green()
2303
+ target_blue = colour.Blue()
2304
+
2305
+ h, s, v = colorsys.rgb_to_hsv(target_red / 255.0, target_green / 255.0,
2306
+ target_blue / 255.0)
2307
+ v = 1.0
2308
+ vstep = 1.0/(brightRect.height-1)
2309
+
2310
+ for y_pos in range(brightRect.y, brightRect.height+brightRect.y):
2311
+ r, g, b = [c * 255.0 for c in colorsys.hsv_to_rgb(h, s, v)]
2312
+ colour = wx.Colour(int(r), int(g), int(b))
2313
+ dc.SetPen(wx.Pen(colour, 1, wx.PENSTYLE_SOLID))
2314
+ dc.DrawRectangle(brightRect.x, y_pos, brightRect.width, 1)
2315
+ v = v - vstep
2316
+
2317
+ dc.SetPen(wx.BLACK_PEN)
2318
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
2319
+ dc.DrawRectangle(brightRect)
2320
+
2321
+ self.DrawMarkers(dc)
2322
+
2323
+
2324
+ def TrackPoint(self, pt):
2325
+ """
2326
+ Tracks a mouse action inside the palette control.
2327
+
2328
+ :param `pt`: an instance of :class:`wx.Point`.
2329
+ """
2330
+
2331
+ brightRect = self.BuildRect()
2332
+ d = brightRect.GetBottom() - pt.y
2333
+ d *= 255.0
2334
+ d /= brightRect.height
2335
+ if d < 0:
2336
+ d = 0
2337
+ if d > 255:
2338
+ d = 255
2339
+
2340
+ mainDialog = self._mainDialog
2341
+ colour = mainDialog._colour
2342
+
2343
+ mainDialog.DrawMarkers()
2344
+ colour.v = int(d)
2345
+
2346
+ colour.ToRGB()
2347
+ mainDialog.SetSpinVals()
2348
+
2349
+ mainDialog.CalcRects()
2350
+ mainDialog.CalcCuboid()
2351
+ mainDialog.DrawMarkers()
2352
+ mainDialog.DrawAlpha()
2353
+
2354
+
2355
+ def DrawMarkers(self, dc=None):
2356
+ """
2357
+ Draws square markers used with mouse gestures.
2358
+
2359
+ :param `dc`: an instance of :class:`wx.DC`.
2360
+ """
2361
+
2362
+ if dc is None:
2363
+ dc = wx.ClientDC(self)
2364
+
2365
+ colour = self._mainDialog._colour
2366
+ brightRect = self.BuildRect()
2367
+
2368
+ y = int(colour.v/255.0*brightRect.height)
2369
+ y = brightRect.GetBottom() - y
2370
+ brightMark = wx.Rect(brightRect.x-2, y-4, brightRect.width+4, 8)
2371
+
2372
+ oldPen, oldBrush, oldMode = dc.GetPen(), dc.GetBrush(), dc.GetLogicalFunction()
2373
+ dc.SetPen(wx.Pen(wx.WHITE, 2))
2374
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
2375
+ dc.SetLogicalFunction(wx.XOR)
2376
+
2377
+ dc.DrawRectangle(brightMark)
2378
+ RestoreOldDC(dc, oldPen, oldBrush, oldMode)
2379
+
2380
+
2381
+ class AlphaCtrl(BaseLineCtrl):
2382
+ """
2383
+ Implements the drawing, mouse handling and sizing routines for the alpha
2384
+ channel control.
2385
+ """
2386
+
2387
+ def __init__(self, parent):
2388
+ """
2389
+ Default class constructor.
2390
+ Used internally. Do not call it in your code!
2391
+
2392
+ :param `parent`: the control parent window.
2393
+ """
2394
+
2395
+ BaseLineCtrl.__init__(self, parent)
2396
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
2397
+
2398
+
2399
+ def OnPaint(self, event):
2400
+ """
2401
+ Handles the ``wx.EVT_PAINT`` for :class:`AlphaCtrl`.
2402
+
2403
+ :param `event`: a :class:`PaintEvent` event to be processed.
2404
+ """
2405
+
2406
+ pdc = wx.PaintDC(self)
2407
+ dc = wx.GCDC(pdc)
2408
+
2409
+ mem_dc = wx.MemoryDC()
2410
+ fullRect = self.GetClientRect()
2411
+ bmp = wx.Bitmap(fullRect.width, fullRect.height)
2412
+ mem_dc.SelectObject(bmp)
2413
+
2414
+ rect = self.BuildRect()
2415
+ backBrush = wx.Brush(self.GetParent().GetBackgroundColour())
2416
+ mem_dc.SetBackground(backBrush)
2417
+ mem_dc.Clear()
2418
+
2419
+ mem_dc.SetBrush(wx.WHITE_BRUSH)
2420
+ mem_dc.DrawRectangle(rect)
2421
+
2422
+ DrawCheckerBoard(mem_dc, rect, checkColour)
2423
+ self.DrawAlphaShading(mem_dc, rect)
2424
+ mem_dc.DestroyClippingRegion()
2425
+
2426
+ self.DrawMarkers(mem_dc)
2427
+
2428
+ mem_dc.SetBrush(wx.TRANSPARENT_BRUSH)
2429
+ mem_dc.SetPen(wx.BLACK_PEN)
2430
+ mem_dc.DrawRectangle(rect)
2431
+
2432
+ mem_dc.SelectObject(wx.NullBitmap)
2433
+ pdc.DrawBitmap(bmp, 0, 0)
2434
+
2435
+
2436
+ def DrawAlphaShading(self, dc, rect):
2437
+ """
2438
+ Draws the alpha shading on top of the checkerboard.
2439
+
2440
+ :param `dc`: an instance of :class:`wx.DC`;
2441
+ :param `rect`: the :class:`AlphaCtrl` client rectangle.
2442
+ """
2443
+
2444
+ gcdc = wx.GCDC(dc)
2445
+
2446
+ colour = self._mainDialog._colour.GetPyColour()
2447
+
2448
+ alpha = 255
2449
+ vstep = 255.0*2/(rect.height-1)
2450
+ r, g, b = colour.Red(), colour.Green(), colour.Blue()
2451
+
2452
+ colour_gcdc = wx.Colour(r, g, b, alpha)
2453
+ gcdc.SetBrush(wx.TRANSPARENT_BRUSH)
2454
+
2455
+ for y_pos in range(rect.y, rect.height+rect.y, 2):
2456
+ colour_gcdc = wx.Colour(r, g, b, int(alpha))
2457
+ gcdc.SetPen(wx.Pen(colour_gcdc, 1, wx.PENSTYLE_SOLID))
2458
+ gcdc.DrawRectangle(rect.x, y_pos, rect.width, 2)
2459
+ alpha = alpha - vstep
2460
+
2461
+
2462
+ def TrackPoint(self, pt):
2463
+ """
2464
+ Tracks a mouse action inside the Alpha channel control.
2465
+
2466
+ :param `pt`: an instance of :class:`wx.Point`.
2467
+ """
2468
+
2469
+ alphaRect = self.BuildRect()
2470
+ d = alphaRect.GetBottom() - pt.y
2471
+ d *= 255.0
2472
+ d /= alphaRect.height
2473
+ if d < 0:
2474
+ d = 0
2475
+ if d > 255:
2476
+ d = 255
2477
+
2478
+ self._mainDialog._colour._alpha = int(d)
2479
+ self.Refresh()
2480
+ self._mainDialog.SetSpinVals()
2481
+
2482
+
2483
+ def DrawMarkers(self, dc=None):
2484
+ """
2485
+ Draws square markers used with mouse gestures.
2486
+
2487
+ :param `dc`: an instance of :class:`wx.DC`.
2488
+ """
2489
+
2490
+ if dc is None:
2491
+ dc = wx.ClientDC(self)
2492
+
2493
+ colour = self._mainDialog._colour
2494
+ alphaRect = self.BuildRect()
2495
+
2496
+ y = int(colour._alpha/255.0*alphaRect.height)
2497
+ y = alphaRect.GetBottom() - y
2498
+ alphaMark = wx.Rect(alphaRect.x-2, y-4, alphaRect.width+4, 8)
2499
+
2500
+ oldPen, oldBrush, oldMode = dc.GetPen(), dc.GetBrush(), dc.GetLogicalFunction()
2501
+ dc.SetPen(wx.Pen(wx.WHITE, 2))
2502
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
2503
+ dc.SetLogicalFunction(wx.XOR)
2504
+
2505
+ dc.DrawRectangle(alphaMark)
2506
+ RestoreOldDC(dc, oldPen, oldBrush, oldMode)
2507
+
2508
+
2509
+ class ColourPanel(wx.Panel):
2510
+ """
2511
+ Simple custom class used to display "old" and "new" colour panels, with alpha
2512
+ blending capabilities.
2513
+ """
2514
+
2515
+ def __init__(self, parent, style=wx.SIMPLE_BORDER):
2516
+ """
2517
+ Default class constructor.
2518
+ Used internally. Do not call it in your code!
2519
+
2520
+ :param `parent`: the control parent window;
2521
+ :param `style`: the :class:`wx.ColourPanel` window style.
2522
+ """
2523
+
2524
+ wx.Panel.__init__(self, parent, style=style)
2525
+ self._mainDialog = wx.GetTopLevelParent(self)
2526
+
2527
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
2528
+ self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
2529
+ self.Bind(wx.EVT_SIZE, self.OnSize)
2530
+
2531
+ self._colour = Colour(wx.WHITE)
2532
+
2533
+
2534
+ def OnPaint(self, event):
2535
+ """
2536
+ Handles the ``wx.EVT_PAINT`` for :class:`wx.ColourPanel`.
2537
+
2538
+ :param `event`: a :class:`PaintEvent` event to be processed.
2539
+ """
2540
+
2541
+ pdc = wx.PaintDC(self)
2542
+ dc = wx.GCDC(pdc)
2543
+
2544
+ mem_dc = wx.MemoryDC()
2545
+ rect = self.GetClientRect()
2546
+ bmp = wx.Bitmap(rect.width, rect.height)
2547
+ mem_dc.SelectObject(bmp)
2548
+
2549
+ backBrush = wx.Brush(self.GetParent().GetBackgroundColour())
2550
+ mem_dc.SetBackground(backBrush)
2551
+ mem_dc.Clear()
2552
+
2553
+ mem_dc.SetBrush(wx.WHITE_BRUSH)
2554
+ mem_dc.DrawRectangle(rect)
2555
+
2556
+ DrawCheckerBoard(mem_dc, rect, checkColour, box=10)
2557
+
2558
+ gcdc = wx.GCDC(mem_dc)
2559
+ colour_gcdc = wx.Colour(self._colour.r, self._colour.g, self._colour.b, self._colour._alpha)
2560
+ gcdc.SetBrush(wx.Brush(colour_gcdc))
2561
+ gcdc.SetPen(wx.Pen(colour_gcdc))
2562
+ gcdc.DrawRectangle(rect)
2563
+
2564
+ mem_dc.SelectObject(wx.NullBitmap)
2565
+ dc.DrawBitmap(bmp, 0, 0)
2566
+
2567
+
2568
+ def OnEraseBackground(self, event):
2569
+ """
2570
+ Handles the ``wx.EVT_ERASE_BACKGROUND`` for :class:`wx.ColourPanel`.
2571
+
2572
+ :param `event`: a :class:`EraseEvent` event to be processed.
2573
+
2574
+ :note: This is intentionally empty to reduce flicker.
2575
+ """
2576
+
2577
+ pass
2578
+
2579
+
2580
+ def OnSize(self, event):
2581
+ """
2582
+ Handles the ``wx.EVT_SIZE`` for :class:`wx.ColourPanel`.
2583
+
2584
+ :param `event`: a :class:`wx.SizeEvent` event to be processed.
2585
+ """
2586
+
2587
+ self.Refresh()
2588
+
2589
+
2590
+ def RefreshColour(self, colour):
2591
+ """
2592
+ Refresh the panel after a colour/alpha change.
2593
+
2594
+ :param `colour`: the new background colour of :class:`wx.ColourPanel`.
2595
+ """
2596
+
2597
+ self._colour = colour
2598
+ self.Refresh()
2599
+
2600
+
2601
+ def AcceptsFocusFromKeyboard(self):
2602
+ """
2603
+ Can this window be given focus by keyboard navigation? If not, the
2604
+ only way to give it focus (provided it accepts it at all) is to click
2605
+ it.
2606
+
2607
+ :note: This method always returns ``False`` as we do not accept focus from
2608
+ the keyboard.
2609
+
2610
+ :note: Overridden from :class:`Panel`.
2611
+ """
2612
+
2613
+ return False
2614
+
2615
+
2616
+ def AcceptsFocus(self):
2617
+ """
2618
+ Can this window be given focus by mouse click?
2619
+
2620
+ :note: This method always returns ``False`` as we do not accept focus from
2621
+ mouse click.
2622
+
2623
+ :note: Overridden from :class:`Panel`.
2624
+ """
2625
+
2626
+ return False
2627
+
2628
+
2629
+ class CustomPanel(wx.Control):
2630
+ """
2631
+ This panel displays a series of custom colours (chosen by the user) just like
2632
+ the standard :class:`wx.ColourDialog`.
2633
+ """
2634
+
2635
+ def __init__(self, parent, colourData):
2636
+ """
2637
+ Default class constructor.
2638
+ Used internally. Do not call it in your code!
2639
+
2640
+ :param `parent`: the control parent window;
2641
+ :param `colourData`: an instance of :class:`wx.ColourData`.
2642
+ """
2643
+
2644
+ wx.Control.__init__(self, parent, style=wx.NO_BORDER)
2645
+ self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
2646
+
2647
+ self._colourData = colourData
2648
+ self._customColours = [None]*16
2649
+ self._mainDialog = wx.GetTopLevelParent(self)
2650
+
2651
+ self.InitializeColours()
2652
+
2653
+ self._smallRectangleSize = wx.Size(20, 16)
2654
+ self._gridSpacing = 4
2655
+ self._customColourRect = wx.Rect(2, 2, (8*self._smallRectangleSize.x) + (7*self._gridSpacing),
2656
+ (2*self._smallRectangleSize.y) + (1*self._gridSpacing))
2657
+
2658
+ self.Bind(wx.EVT_PAINT, self.OnPaint)
2659
+ self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)
2660
+ self.Bind(wx.EVT_SIZE, self.OnSize)
2661
+ self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
2662
+
2663
+
2664
+ def InitializeColours(self):
2665
+ """ Initializes the 16 custom colours in :class:`CustomPanel`. """
2666
+
2667
+ curr = self._colourData.GetColour()
2668
+ self._colourSelection = -1
2669
+
2670
+ for i in range(16):
2671
+ c = self._colourData.GetCustomColour(i)
2672
+ if c.IsOk():
2673
+ self._customColours[i] = self._colourData.GetCustomColour(i)
2674
+ else:
2675
+ self._customColours[i] = wx.WHITE
2676
+
2677
+ if c == curr:
2678
+ self._colourSelection = i
2679
+
2680
+
2681
+ def DoGetBestSize(self):
2682
+ """
2683
+ Overridden base class virtual. Determines the best size of the control.
2684
+
2685
+ :note: Overridden from :class:`wx.Control`.
2686
+ """
2687
+
2688
+ return self._customColourRect.width+4, self._customColourRect.height+4
2689
+
2690
+
2691
+ def OnPaint(self, event):
2692
+ """
2693
+ Handles the ``wx.EVT_PAINT`` for :class:`CustomPanel`.
2694
+
2695
+ :param `event`: a :class:`PaintEvent` event to be processed.
2696
+ """
2697
+
2698
+ dc = wx.AutoBufferedPaintDC(self)
2699
+ dc.SetBackground(wx.Brush(self.GetParent().GetBackgroundColour()))
2700
+ dc.Clear()
2701
+
2702
+ self.PaintCustomColours(dc)
2703
+ self.PaintHighlight(dc, True)
2704
+
2705
+
2706
+ def OnEraseBackground(self, event):
2707
+ """
2708
+ Handles the ``wx.EVT_ERASE_BACKGROUND`` for :class:`CustomPanel`.
2709
+
2710
+ :param `event`: a :class:`EraseEvent` event to be processed.
2711
+
2712
+ :note: This is intentionally empty to reduce flicker.
2713
+ """
2714
+
2715
+ pass
2716
+
2717
+
2718
+ def OnSize(self, event):
2719
+ """
2720
+ Handles the ``wx.EVT_SIZE`` for :class:`CustomPanel`.
2721
+
2722
+ :param `event`: a :class:`wx.SizeEvent` event to be processed.
2723
+ """
2724
+
2725
+ self.Refresh()
2726
+
2727
+
2728
+ def OnLeftDown(self, event):
2729
+ """
2730
+ Handles the ``wx.EVT_LEFT_DOWN`` for :class:`CustomPanel`.
2731
+
2732
+ :param `event`: a :class:`MouseEvent` event to be processed.
2733
+ """
2734
+
2735
+ x, y = event.GetX(), event.GetY()
2736
+
2737
+ selX = (x - self._customColourRect.x)//(self._smallRectangleSize.x + self._gridSpacing)
2738
+ selY = (y - self._customColourRect.y)//(self._smallRectangleSize.y + self._gridSpacing)
2739
+ ptr = selX + selY*8
2740
+
2741
+ dc = wx.ClientDC(self)
2742
+ self.PaintHighlight(dc, False)
2743
+ self._colourSelection = ptr
2744
+
2745
+ self._mainDialog._colour = Colour(self._customColours[self._colourSelection])
2746
+
2747
+ self.PaintCustomColour(dc, selX, selY)
2748
+ self.PaintHighlight(dc, True)
2749
+ self._mainDialog.DrawAll()
2750
+
2751
+
2752
+ def PaintCustomColours(self, dc):
2753
+ """
2754
+ Draws all the 16 subpanels with their custom colours.
2755
+
2756
+ :param `dc`: an instance of :class:`wx.DC`.
2757
+ """
2758
+
2759
+ for i in range(2):
2760
+ for j in range(8):
2761
+
2762
+ ptr = i*8 + j
2763
+ x = (j*(self._smallRectangleSize.x+self._gridSpacing)) + self._customColourRect.x
2764
+ y = (i*(self._smallRectangleSize.y+self._gridSpacing)) + self._customColourRect.y
2765
+
2766
+ dc.SetPen(wx.BLACK_PEN)
2767
+
2768
+ brush = wx.Brush(self._customColours[ptr])
2769
+ dc.SetBrush(brush)
2770
+
2771
+ dc.DrawRectangle(x, y, self._smallRectangleSize.x, self._smallRectangleSize.y)
2772
+
2773
+
2774
+ def PaintHighlight(self, dc, draw=True):
2775
+ """
2776
+ Highlight the current custom colour selection (if any).
2777
+
2778
+ :param `dc`: an instance of :class:`wx.DC`;
2779
+ :param `draw`: whether to draw a thin black border around the selected custom
2780
+ colour or not.
2781
+ """
2782
+
2783
+ if self._colourSelection < 0:
2784
+ return
2785
+
2786
+ # Number of pixels bigger than the standard rectangle size
2787
+ # for drawing a highlight
2788
+ deltaX = deltaY = 2
2789
+
2790
+ # User-defined colours
2791
+ y = self._colourSelection//8
2792
+ x = self._colourSelection - (y*8)
2793
+
2794
+ x = (x*(self._smallRectangleSize.x + self._gridSpacing) + self._customColourRect.x) - deltaX
2795
+ y = (y*(self._smallRectangleSize.y + self._gridSpacing) + self._customColourRect.y) - deltaY
2796
+
2797
+ if draw:
2798
+ dc.SetPen(wx.BLACK_PEN)
2799
+ else:
2800
+ dc.SetPen(wx.LIGHT_GREY_PEN)
2801
+
2802
+ dc.SetBrush(wx.TRANSPARENT_BRUSH)
2803
+ dc.DrawRectangle(x, y, (self._smallRectangleSize.x + (2*deltaX)), (self._smallRectangleSize.y + (2*deltaY)))
2804
+
2805
+
2806
+ def PaintCustomColour(self, dc, selX, selY):
2807
+ """
2808
+ Paints a newly added custom colour subpanel.
2809
+
2810
+ :param `dc`: an instance of :class:`wx.DC`;
2811
+ :param `selX`: the x coordinate of the custom colour subpanel;
2812
+ :param `selY`: the y coordinate of the custom colour subpanel.
2813
+ """
2814
+
2815
+ dc.SetPen(wx.BLACK_PEN)
2816
+
2817
+ brush = wx.Brush(self._customColours[self._colourSelection])
2818
+ dc.SetBrush(brush)
2819
+
2820
+ ptr = selX*8 + selY
2821
+ x = (selX*(self._smallRectangleSize.x+self._gridSpacing)) + self._customColourRect.x
2822
+ y = (selY*(self._smallRectangleSize.y+self._gridSpacing)) + self._customColourRect.y
2823
+
2824
+ dc.DrawRectangle(x, y, self._smallRectangleSize.x, self._smallRectangleSize.y)
2825
+
2826
+ dc.SetBrush(wx.NullBrush)
2827
+
2828
+
2829
+ def AddCustom(self, colour):
2830
+ """
2831
+ Adds a user-chosen colour to the list of custom colours.
2832
+
2833
+ :param `colour`: an instance of :class:`wx.Colour`.
2834
+ """
2835
+
2836
+ self._colourSelection += 1
2837
+ self._colourSelection = self._colourSelection%16
2838
+
2839
+ dc = wx.ClientDC(self)
2840
+ self._customColours[self._colourSelection] = colour.GetPyColour()
2841
+ self._colourData.SetCustomColour(self._colourSelection, self._customColours[self._colourSelection])
2842
+
2843
+ self.PaintCustomColours(dc)
2844
+
2845
+
2846
+ class CubeColourDialog(wx.Dialog):
2847
+ """
2848
+ This is the CubeColourDialog main class implementation.
2849
+ """
2850
+
2851
+ def __init__(self, parent, colourData=None, agwStyle=CCD_SHOW_ALPHA):
2852
+ """
2853
+ Default class constructor.
2854
+
2855
+ :param `colourData`: a standard :class:`wx.ColourData` (as used in :class:`wx.ColourDialog`);
2856
+ :param `agwStyle`: can be either ``None`` or ``CCD_SHOW_ALPHA``, depending if you want
2857
+ to hide the alpha channel control or not.
2858
+ """
2859
+
2860
+ wx.Dialog.__init__(self, parent, id=wx.ID_ANY, title=_("CubeColourDialog: Choose Colour"),
2861
+ pos=wx.DefaultPosition, size=(900, 900), style=wx.DEFAULT_DIALOG_STYLE)
2862
+
2863
+ if colourData:
2864
+ self._colourData = colourData
2865
+ else:
2866
+ self._colourData = wx.ColourData()
2867
+ self._colourData.SetColour(wx.Colour(128, 128, 128))
2868
+
2869
+ self._colour = Colour(self._colourData.GetColour())
2870
+ self._oldColour = Colour(self._colourData.GetColour())
2871
+
2872
+ self._inMouse = False
2873
+ self._initOver = False
2874
+ self._inDrawAll = False
2875
+ self._agwStyle = agwStyle
2876
+
2877
+ self.mainPanel = wx.Panel(self, -1)
2878
+
2879
+ self.hsvSizer_staticbox = wx.StaticBox(self.mainPanel, -1, _("HSB"))
2880
+ self.rgbValueSizer_staticbox = wx.StaticBox(self.mainPanel, -1, _("RGB Values"))
2881
+ self.hsvValueSizer_staticbox = wx.StaticBox(self.mainPanel, -1, _("HSB Values"))
2882
+ self.rgbSizer_staticbox = wx.StaticBox(self.mainPanel, -1, _("RGB"))
2883
+ self.alphaSizer_staticbox = wx.StaticBox(self.mainPanel, -1, _("Alpha"))
2884
+ self.alphaValueSizer_staticbox = wx.StaticBox(self.mainPanel, -1, _("Alpha"))
2885
+
2886
+ self.rgbBitmap = RGBCube(self.mainPanel)
2887
+ self.hsvBitmap = HSVWheel(self.mainPanel)
2888
+ self.brightCtrl = BrightCtrl(self.mainPanel)
2889
+ self.alphaCtrl = AlphaCtrl(self.mainPanel)
2890
+
2891
+ self.showAlpha = wx.CheckBox(self.mainPanel, -1, _("Show Alpha Control"))
2892
+ self.customColours = CustomPanel(self.mainPanel, self._colourData)
2893
+ self.addCustom = wx.Button(self.mainPanel, -1, _("Add to custom colours"))
2894
+
2895
+ self.okButton = wx.Button(self.mainPanel, -1, _("OK"))
2896
+ self.cancelButton = wx.Button(self.mainPanel, -1, _("Cancel"))
2897
+
2898
+ self.oldColourPanel = ColourPanel(self.mainPanel, style=wx.SIMPLE_BORDER)
2899
+ self.newColourPanel = ColourPanel(self.mainPanel, style=wx.SIMPLE_BORDER)
2900
+
2901
+ self.redSpin = wx.SpinCtrl(self.mainPanel, -1, "180", min=0, max=255,
2902
+ style=wx.SP_ARROW_KEYS)
2903
+ self.greenSpin = wx.SpinCtrl(self.mainPanel, -1, "180", min=0, max=255,
2904
+ style=wx.SP_ARROW_KEYS)
2905
+ self.blueSpin = wx.SpinCtrl(self.mainPanel, -1, "180", min=0, max=255,
2906
+ style=wx.SP_ARROW_KEYS)
2907
+ self.hueSpin = wx.SpinCtrl(self.mainPanel, -1, "0", min=0, max=359,
2908
+ style=wx.SP_ARROW_KEYS)
2909
+ self.saturationSpin = wx.SpinCtrl(self.mainPanel, -1, "", min=0, max=255,
2910
+ style=wx.SP_ARROW_KEYS)
2911
+ self.brightnessSpin = wx.SpinCtrl(self.mainPanel, -1, "", min=0, max=255,
2912
+ style=wx.SP_ARROW_KEYS)
2913
+ self.alphaSpin = wx.SpinCtrl(self.mainPanel, -1, "", min=0, max=255,
2914
+ style=wx.SP_ARROW_KEYS)
2915
+ self.accessCode = wx.TextCtrl(self.mainPanel, -1, "", style=wx.TE_READONLY)
2916
+ self.htmlCode = wx.TextCtrl(self.mainPanel, -1, "", style=wx.TE_READONLY)
2917
+ self.webSafe = wx.TextCtrl(self.mainPanel, -1, "", style=wx.TE_READONLY)
2918
+ self.htmlName = wx.TextCtrl(self.mainPanel, -1, "", style=wx.TE_READONLY)
2919
+
2920
+ self.SetProperties()
2921
+ self.DoLayout()
2922
+
2923
+ self.spinCtrls = [self.redSpin, self.greenSpin, self.blueSpin,
2924
+ self.hueSpin, self.saturationSpin, self.brightnessSpin]
2925
+
2926
+ for spin in self.spinCtrls:
2927
+ spin.Bind(wx.EVT_SPINCTRL, self.OnSpinCtrl)
2928
+
2929
+ self.Bind(wx.EVT_SPINCTRL, self.OnAlphaSpin, self.alphaSpin)
2930
+
2931
+ self.Bind(wx.EVT_BUTTON, self.OnOk, self.okButton)
2932
+ self.Bind(wx.EVT_BUTTON, self.OnCancel, self.cancelButton)
2933
+ self.Bind(wx.EVT_BUTTON, self.OnAddCustom, self.addCustom)
2934
+
2935
+ self.Bind(wx.EVT_CHECKBOX, self.OnShowAlpha)
2936
+ self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
2937
+ self.Bind(wx.EVT_CHAR_HOOK, self.OnKeyUp)
2938
+
2939
+ self.Centre(wx.BOTH)
2940
+
2941
+ wx.CallAfter(self.InitDialog)
2942
+
2943
+
2944
+ def SetProperties(self):
2945
+ """ Sets some initial properties for :class:`CubeColourDialog` (sizes, values). """
2946
+
2947
+ # Adjust for GTK3's wider SpinButtons
2948
+ spinWidth = 120 if 'gtk3' in wx.PlatformInfo else 60
2949
+ self.okButton.SetDefault()
2950
+ self.oldColourPanel.SetMinSize((-1, 50))
2951
+ self.newColourPanel.SetMinSize((-1, 50))
2952
+ self.redSpin.SetMinSize((spinWidth, -1))
2953
+ self.greenSpin.SetMinSize((spinWidth, -1))
2954
+ self.blueSpin.SetMinSize((spinWidth, -1))
2955
+ self.hueSpin.SetMinSize((spinWidth, -1))
2956
+ self.saturationSpin.SetMinSize((spinWidth, -1))
2957
+ self.brightnessSpin.SetMinSize((spinWidth, -1))
2958
+ self.alphaSpin.SetMinSize((spinWidth, -1))
2959
+ self.showAlpha.SetValue(1)
2960
+ self.accessCode.SetInitialSize((80, -1))
2961
+ self.webSafe.SetInitialSize((80, -1))
2962
+ self.htmlCode.SetInitialSize((80, -1))
2963
+
2964
+
2965
+ def DoLayout(self):
2966
+ """ Layouts all the controls in the :class:`CubeColourDialog`. """
2967
+
2968
+ dialogSizer = wx.BoxSizer(wx.VERTICAL)
2969
+ mainSizer = wx.GridBagSizer(10, 5)
2970
+ hsvValueSizer = wx.StaticBoxSizer(self.hsvValueSizer_staticbox, wx.VERTICAL)
2971
+ hsvGridSizer = wx.GridSizer(2, 3, 2, 10)
2972
+ rgbValueSizer = wx.StaticBoxSizer(self.rgbValueSizer_staticbox, wx.HORIZONTAL)
2973
+ rgbGridSizer = wx.GridSizer(2, 3, 2, 10)
2974
+ alphaValueSizer = wx.StaticBoxSizer(self.alphaValueSizer_staticbox, wx.VERTICAL)
2975
+ alphaGridSizer = wx.BoxSizer(wx.VERTICAL)
2976
+ customSizer = wx.BoxSizer(wx.VERTICAL)
2977
+ buttonSizer = wx.BoxSizer(wx.VERTICAL)
2978
+ accessSizer = wx.BoxSizer(wx.VERTICAL)
2979
+ panelSizer = wx.BoxSizer(wx.VERTICAL)
2980
+ htmlSizer1 = wx.BoxSizer(wx.HORIZONTAL)
2981
+ htmlSizer2 = wx.BoxSizer(wx.VERTICAL)
2982
+ htmlSizer_a = wx.BoxSizer(wx.VERTICAL)
2983
+ htmlSizer_b = wx.BoxSizer(wx.VERTICAL)
2984
+
2985
+ hsvSizer = wx.StaticBoxSizer(self.hsvSizer_staticbox, wx.HORIZONTAL)
2986
+ rgbSizer = wx.StaticBoxSizer(self.rgbSizer_staticbox, wx.VERTICAL)
2987
+ alphaSizer = wx.StaticBoxSizer(self.alphaSizer_staticbox, wx.VERTICAL)
2988
+
2989
+ mainSizer.Add(self.showAlpha, (0, 0), (1, 1), wx.LEFT|wx.TOP, 10)
2990
+
2991
+ htmlLabel1 = wx.StaticText(self.mainPanel, -1, _("HTML Code"))
2992
+ htmlLabel2 = wx.StaticText(self.mainPanel, -1, _("Web Safe"))
2993
+ htmlSizer_a.Add(htmlLabel1, 0, wx.TOP, 3)
2994
+ htmlSizer_b.Add(htmlLabel2, 0, wx.TOP, 3)
2995
+ htmlSizer_a.Add(self.htmlCode, 0, wx.TOP, 3)
2996
+ htmlSizer_b.Add(self.webSafe, 0, wx.TOP, 3)
2997
+
2998
+ htmlSizer1.Add(htmlSizer_a, 0)
2999
+ htmlSizer1.Add(htmlSizer_b, 0, wx.LEFT, 10)
3000
+ mainSizer.Add(htmlSizer1, (1, 0), (1, 1), wx.LEFT|wx.RIGHT, 10)
3001
+
3002
+ htmlLabel3 = wx.StaticText(self.mainPanel, -1, _("HTML Name"))
3003
+ htmlSizer2.Add(htmlLabel3, 0, wx.TOP|wx.BOTTOM, 3)
3004
+ htmlSizer2.Add(self.htmlName, 0)
3005
+
3006
+ mainSizer.Add(htmlSizer2, (1, 1), (1, 1), wx.LEFT|wx.RIGHT, 10)
3007
+
3008
+ customLabel = wx.StaticText(self.mainPanel, -1, _("Custom Colours"))
3009
+ customSizer.Add(customLabel, 0, wx.BOTTOM, 3)
3010
+ customSizer.Add(self.customColours, 0)
3011
+ customSizer.Add(self.addCustom, 0, wx.TOP|wx.ALIGN_LEFT, 5)
3012
+ mainSizer.Add(customSizer, (0, 2), (2, 2), wx.ALIGN_CENTER|wx.LEFT|wx.RIGHT, 5)
3013
+
3014
+ rgbSizer.Add(self.rgbBitmap, 0, wx.ALL, 15)
3015
+ mainSizer.Add(rgbSizer, (2, 0), (1, 1), wx.ALL|wx.EXPAND, 10)
3016
+ hsvSizer.Add(self.hsvBitmap, 0, wx.ALL, 15)
3017
+ hsvSizer.Add(self.brightCtrl, 0, wx.RIGHT|wx.TOP|wx.BOTTOM, 15)
3018
+ mainSizer.Add(hsvSizer, (2, 1), (1, 1), wx.ALL|wx.EXPAND, 10)
3019
+ alphaSizer.Add(self.alphaCtrl, 0, wx.TOP|wx.ALIGN_CENTER, 15)
3020
+ mainSizer.Add(alphaSizer, (2, 2), (1, 1), wx.ALL|wx.EXPAND, 10)
3021
+
3022
+ oldLabel = wx.StaticText(self.mainPanel, -1, _("Old Colour"))
3023
+ panelSizer.Add(oldLabel, 0, wx.BOTTOM, 3)
3024
+ panelSizer.Add(self.oldColourPanel, 0, wx.BOTTOM|wx.EXPAND, 20)
3025
+ newLabel = wx.StaticText(self.mainPanel, -1, _("New Colour"))
3026
+ accessLabel = wx.StaticText(self.mainPanel, -1, _("MS Access Code"))
3027
+ accessSizer.Add(accessLabel, 0, wx.BOTTOM, 3)
3028
+ accessSizer.Add(self.accessCode, 0)
3029
+ panelSizer.Add(newLabel, 0, wx.BOTTOM, 3)
3030
+ panelSizer.Add(self.newColourPanel, 0, wx.EXPAND)
3031
+ panelSizer.Add(0, 0, 1, wx.EXPAND)
3032
+ panelSizer.Add(accessSizer, 0, wx.TOP, 5)
3033
+ mainSizer.Add(panelSizer, (2, 3), (1, 1), wx.ALL|wx.EXPAND, 10)
3034
+ redLabel = wx.StaticText(self.mainPanel, -1, _("Red"))
3035
+ rgbGridSizer.Add(redLabel, 0)
3036
+ greenLabel = wx.StaticText(self.mainPanel, -1, _("Green"))
3037
+ rgbGridSizer.Add(greenLabel, 0)
3038
+ blueLabel = wx.StaticText(self.mainPanel, -1, _("Blue"))
3039
+ rgbGridSizer.Add(blueLabel, 0)
3040
+ rgbGridSizer.Add(self.redSpin, 0, wx.EXPAND)
3041
+ rgbGridSizer.Add(self.greenSpin, 0, wx.EXPAND)
3042
+ rgbGridSizer.Add(self.blueSpin, 0, wx.EXPAND)
3043
+ rgbValueSizer.Add(rgbGridSizer, 1, 0, 0)
3044
+ mainSizer.Add(rgbValueSizer, (3, 0), (1, 1), wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, 10)
3045
+ hueLabel = wx.StaticText(self.mainPanel, -1, _("Hue"))
3046
+ hsvGridSizer.Add(hueLabel, 0)
3047
+ saturationLabel = wx.StaticText(self.mainPanel, -1, _("Saturation"))
3048
+ hsvGridSizer.Add(saturationLabel, 0)
3049
+ brightnessLabel = wx.StaticText(self.mainPanel, -1, _("Brightness"))
3050
+ hsvGridSizer.Add(brightnessLabel, 0)
3051
+ hsvGridSizer.Add(self.hueSpin, 0, wx.EXPAND)
3052
+ hsvGridSizer.Add(self.saturationSpin, 0, wx.EXPAND)
3053
+ hsvGridSizer.Add(self.brightnessSpin, 0, wx.EXPAND)
3054
+ hsvValueSizer.Add(hsvGridSizer, 1, wx.EXPAND)
3055
+ mainSizer.Add(hsvValueSizer, (3, 1), (1, 1), wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, 10)
3056
+ alphaLabel = wx.StaticText(self.mainPanel, -1, _("Alpha"))
3057
+ alphaGridSizer.Add(alphaLabel, 0)
3058
+ alphaGridSizer.Add(self.alphaSpin, 0, wx.EXPAND|wx.TOP, 10)
3059
+ alphaValueSizer.Add(alphaGridSizer, 1, wx.EXPAND)
3060
+ mainSizer.Add(alphaValueSizer, (3, 2), (1, 1), wx.LEFT|wx.RIGHT|wx.BOTTOM|wx.EXPAND, 10)
3061
+ buttonSizer.Add(self.okButton, 0, wx.BOTTOM, 3)
3062
+ buttonSizer.Add(self.cancelButton, 0)
3063
+ mainSizer.Add(buttonSizer, (3, 3), (1, 1), wx.ALIGN_CENTER|wx.LEFT|wx.RIGHT, 5)
3064
+
3065
+ self.mainPanel.SetAutoLayout(True)
3066
+ self.mainPanel.SetSizer(mainSizer)
3067
+ mainSizer.Fit(self.mainPanel)
3068
+ mainSizer.SetSizeHints(self.mainPanel)
3069
+
3070
+ if self.GetAGWWindowStyleFlag() & CCD_SHOW_ALPHA == 0:
3071
+ mainSizer.Hide(self.showAlpha)
3072
+ mainSizer.Hide(alphaSizer)
3073
+ mainSizer.Hide(alphaValueSizer)
3074
+
3075
+ dialogSizer.Add(self.mainPanel, 1, wx.EXPAND)
3076
+ self.SetAutoLayout(True)
3077
+ self.SetSizer(dialogSizer)
3078
+ dialogSizer.Fit(self)
3079
+ dialogSizer.SetSizeHints(self)
3080
+ self.Layout()
3081
+
3082
+ self.mainSizer = mainSizer
3083
+ self.dialogSizer = dialogSizer
3084
+ self.alphaSizers = [alphaSizer, alphaValueSizer]
3085
+
3086
+
3087
+ def InitDialog(self):
3088
+ """ Initialize the :class:`CubeColourDialog`. """
3089
+
3090
+ hsvRect = self.hsvBitmap.GetClientRect()
3091
+ self._centre = wx.Point(hsvRect.x + hsvRect.width//2, hsvRect.y + hsvRect.height//2)
3092
+
3093
+ self._redLen = Distance(Vertex, Top)
3094
+ self._greenLen = Distance(Vertex, Left)
3095
+ self._blueLen = Distance(Vertex, Right)
3096
+
3097
+ self.CalcSlopes()
3098
+ self.CalcCuboid()
3099
+ self.CalcRects()
3100
+
3101
+ self.SetSpinVals()
3102
+
3103
+ self._initOver = True
3104
+ wx.CallAfter(self.Refresh)
3105
+
3106
+
3107
+ def CalcSlopes(self):
3108
+ """ Calculates the line slopes in the RGB colour cube. """
3109
+
3110
+ self._lines = {RED: LineDescription(), GREEN: LineDescription(), BLUE: LineDescription}
3111
+
3112
+ self._lines[RED].slope = Slope(Top, Vertex)
3113
+ self._lines[GREEN].slope = Slope(Left, Vertex)
3114
+ self._lines[BLUE].slope = Slope(Right, Vertex)
3115
+
3116
+ for i in range(3):
3117
+ self._lines[i].x = Vertex.x
3118
+ self._lines[i].y = Vertex.y
3119
+ self._lines[i].c = FindC(self._lines[i])
3120
+
3121
+
3122
+ def CalcCuboid(self):
3123
+ """ Calculates the RGB colour cube vertices. """
3124
+
3125
+ rLen = (self._colour.r*self._redLen)/255.0
3126
+ gLen = (self._colour.g*self._greenLen)/255.0
3127
+ bLen = (self._colour.b*self._blueLen)/255.0
3128
+
3129
+ lines = [LineDescription() for i in range(12)]
3130
+ self._cuboid = [None]*8
3131
+
3132
+ self._cuboid[0] = Vertex
3133
+ self._cuboid[1] = PointOnLine(Vertex, Top, int(rLen), self._redLen)
3134
+ self._cuboid[3] = PointOnLine(Vertex, Left, int(gLen), self._greenLen)
3135
+ self._cuboid[7] = PointOnLine(Vertex, Right, int(bLen), self._blueLen)
3136
+
3137
+ lines[0] = self._lines[RED]
3138
+ lines[1] = self._lines[GREEN]
3139
+ lines[2] = self._lines[BLUE]
3140
+
3141
+ lines[3].slope = self._lines[GREEN].slope
3142
+ lines[3].x = self._cuboid[1].x
3143
+ lines[3].y = self._cuboid[1].y
3144
+ lines[3].c = FindC(lines[3])
3145
+
3146
+ lines[4].slope = self._lines[RED].slope
3147
+ lines[4].x = self._cuboid[3].x
3148
+ lines[4].y = self._cuboid[3].y
3149
+ lines[4].c = FindC(lines[4])
3150
+
3151
+ lines[5].slope = self._lines[BLUE].slope
3152
+ lines[5].x = self._cuboid[3].x
3153
+ lines[5].y = self._cuboid[3].y
3154
+ lines[5].c = FindC(lines[5])
3155
+
3156
+ lines[6].slope = self._lines[GREEN].slope
3157
+ lines[6].x = self._cuboid[7].x
3158
+ lines[6].y = self._cuboid[7].y
3159
+ lines[6].c = FindC(lines[6])
3160
+
3161
+ lines[10].slope = self._lines[BLUE].slope
3162
+ lines[10].x = self._cuboid[1].x
3163
+ lines[10].y = self._cuboid[1].y
3164
+ lines[10].c = FindC(lines[10])
3165
+
3166
+ lines[11].slope = self._lines[RED].slope
3167
+ lines[11].x = self._cuboid[7].x
3168
+ lines[11].y = self._cuboid[7].y
3169
+ lines[11].c = FindC(lines[11])
3170
+
3171
+ self._cuboid[2] = Intersection(lines[3], lines[4])
3172
+ self._cuboid[4] = Intersection(lines[5], lines[6])
3173
+ self._cuboid[6] = Intersection(lines[10], lines[11])
3174
+
3175
+ lines[7].slope = self._lines[RED].slope
3176
+ lines[7].x = self._cuboid[4].x
3177
+ lines[7].y = self._cuboid[4].y
3178
+ lines[7].c = FindC(lines[7])
3179
+
3180
+ lines[8].slope = self._lines[BLUE].slope
3181
+ lines[8].x = self._cuboid[2].x
3182
+ lines[8].y = self._cuboid[2].y
3183
+ lines[8].c = FindC(lines[8])
3184
+
3185
+ self._cuboid[5] = Intersection(lines[7], lines[8])
3186
+
3187
+
3188
+ def CalcRects(self):
3189
+ """ Calculates the brightness control user-selected rect. """
3190
+
3191
+ pt = PtFromAngle(self._colour.h, self._colour.s, self._centre)
3192
+ self._currentRect = wx.Rect(pt.x - RECT_WIDTH, pt.y - RECT_WIDTH,
3193
+ 2*RECT_WIDTH, 2*RECT_WIDTH)
3194
+
3195
+
3196
+ def DrawMarkers(self, dc=None):
3197
+ """
3198
+ Draws the markers for all the controls.
3199
+
3200
+ :param `dc`: an instance of :class:`wx.DC`. If `dc` is ``None``, a :class:`ClientDC` is
3201
+ created on the fly.
3202
+ """
3203
+
3204
+ if dc is None:
3205
+ dc = wx.ClientDC(self)
3206
+
3207
+ self.hsvBitmap.DrawMarkers()
3208
+ self.rgbBitmap.DrawMarkers()
3209
+ self.brightCtrl.DrawMarkers()
3210
+
3211
+
3212
+ def DrawRGB(self):
3213
+ """ Refreshes the RGB colour cube. """
3214
+
3215
+ self.rgbBitmap.Refresh()
3216
+
3217
+
3218
+ def DrawHSB(self):
3219
+ """ Refreshes the HSB colour wheel. """
3220
+
3221
+ self.hsvBitmap.Refresh()
3222
+
3223
+
3224
+ def DrawBright(self):
3225
+ """ Refreshes the brightness control. """
3226
+
3227
+ self.brightCtrl.Refresh()
3228
+
3229
+
3230
+ def DrawAlpha(self):
3231
+ """ Refreshes the alpha channel control. """
3232
+
3233
+ self.alphaCtrl.Refresh()
3234
+
3235
+
3236
+ def SetSpinVals(self):
3237
+ """ Sets the values for all the spin controls. """
3238
+
3239
+ self.redSpin.SetValue(self._colour.r)
3240
+ self.greenSpin.SetValue(self._colour.g)
3241
+ self.blueSpin.SetValue(self._colour.b)
3242
+
3243
+ self.hueSpin.SetValue(self._colour.h)
3244
+ self.saturationSpin.SetValue(self._colour.s)
3245
+ self.brightnessSpin.SetValue(self._colour.v)
3246
+
3247
+ self.alphaSpin.SetValue(self._colour._alpha)
3248
+
3249
+ self.SetPanelColours()
3250
+ self.SetCodes()
3251
+
3252
+
3253
+ def SetPanelColours(self):
3254
+ """ Assigns colours to the colour panels. """
3255
+
3256
+ self.oldColourPanel.RefreshColour(self._oldColour)
3257
+ self.newColourPanel.RefreshColour(self._colour)
3258
+
3259
+
3260
+ def SetCodes(self):
3261
+ """ Sets the HTML/MS Access codes (if any) in the text controls. """
3262
+
3263
+ colour = rgb2html(self._colour)
3264
+ self.htmlCode.SetValue(colour)
3265
+ self.htmlCode.Refresh()
3266
+
3267
+ if colour in HTMLCodes:
3268
+ colourName, access, webSafe = HTMLCodes[colour]
3269
+ self.webSafe.SetValue(webSafe)
3270
+ self.accessCode.SetValue(access)
3271
+ self.htmlName.SetValue(colourName)
3272
+ else:
3273
+ self.webSafe.SetValue("")
3274
+ self.accessCode.SetValue("")
3275
+ self.htmlName.SetValue("")
3276
+
3277
+
3278
+ def OnCloseWindow(self, event):
3279
+ """
3280
+ Handles the ``wx.EVT_CLOSE`` event for :class:`CubeColourDialog`.
3281
+
3282
+ :param `event`: a :class:`CloseEvent` event to be processed.
3283
+ """
3284
+
3285
+ self.EndModal(wx.ID_CANCEL)
3286
+
3287
+
3288
+ def OnKeyUp(self, event):
3289
+ """
3290
+ Handles the ``wx.EVT_CHAR_HOOK`` event for :class:`CubeColourDialog`.
3291
+
3292
+ :param `event`: a :class:`KeyEvent` event to be processed.
3293
+ """
3294
+
3295
+ if event.GetKeyCode() == wx.WXK_ESCAPE:
3296
+ self.EndModal(wx.ID_CANCEL)
3297
+
3298
+ event.Skip()
3299
+
3300
+
3301
+ def ShowModal(self):
3302
+ """
3303
+ Shows :class:`CubeColourDialog` as a modal dialog. Program flow does
3304
+ not return until the dialog has been dismissed with `EndModal`.
3305
+
3306
+ :note: Overridden from :class:`Dialog`.
3307
+ """
3308
+
3309
+ return wx.Dialog.ShowModal(self)
3310
+
3311
+
3312
+ def SetAGWWindowStyleFlag(self, agwStyle):
3313
+ """
3314
+ Sets the :class:`CubeColourDialog` window style flags.
3315
+
3316
+ :param `agwStyle`: can only be ``CCD_SHOW_ALPHA`` or ``None``.
3317
+ """
3318
+
3319
+ show = agwStyle & CCD_SHOW_ALPHA
3320
+ self._agwStyle = agwStyle
3321
+
3322
+ self.mainSizer.Show(self.alphaSizers[0], show)
3323
+ self.mainSizer.Show(self.alphaSizers[1], show)
3324
+
3325
+ self.mainSizer.Fit(self.mainPanel)
3326
+ self.mainSizer.SetSizeHints(self.mainPanel)
3327
+ self.mainSizer.Layout()
3328
+ self.dialogSizer.Fit(self)
3329
+ self.dialogSizer.SetSizeHints(self)
3330
+ self.Layout()
3331
+
3332
+ self.Refresh()
3333
+ self.Update()
3334
+
3335
+
3336
+ def GetAGWWindowStyleFlag(self):
3337
+ """
3338
+ Returns the :class:`CubeColourDialog` window style flags.
3339
+
3340
+ :see: :meth:`~CubeColourDialog.SetAGWWindowStyleFlag` for a list of possible flags.
3341
+ """
3342
+
3343
+ return self._agwStyle
3344
+
3345
+
3346
+ def OnOk(self, event):
3347
+ """
3348
+ Handles the Ok ``wx.EVT_BUTTON`` event for :class:`CubeColourDialog`.
3349
+
3350
+ :param `event`: a :class:`CommandEvent` event to be processed.
3351
+ """
3352
+
3353
+ self.EndModal(wx.ID_OK)
3354
+
3355
+
3356
+ def OnCancel(self, event):
3357
+ """
3358
+ Handles the Cancel ``wx.EVT_BUTTON`` event for :class:`CubeColourDialog`.
3359
+
3360
+ :param `event`: a :class:`CommandEvent` event to be processed.
3361
+ """
3362
+
3363
+ self.OnCloseWindow(event)
3364
+
3365
+
3366
+ def OnAddCustom(self, event):
3367
+ """
3368
+ Handles the Add Custom ``wx.EVT_BUTTON`` event for :class:`CubeColourDialog`.
3369
+
3370
+ :param `event`: a :class:`CommandEvent` event to be processed.
3371
+ """
3372
+
3373
+
3374
+ self.customColours.AddCustom(self._colour)
3375
+
3376
+
3377
+ def OnShowAlpha(self, event):
3378
+ """
3379
+ Shows/hides the alpha channel control in :class:`CubeColourDialog`.
3380
+
3381
+ :param `event`: a :class:`CommandEvent` event to be processed.
3382
+ """
3383
+
3384
+ agwStyle = self.GetAGWWindowStyleFlag()
3385
+ show = event.IsChecked()
3386
+
3387
+ if show:
3388
+ agwStyle |= CCD_SHOW_ALPHA
3389
+ else:
3390
+ agwStyle &= ~CCD_SHOW_ALPHA
3391
+
3392
+ self.SetAGWWindowStyleFlag(agwStyle)
3393
+
3394
+
3395
+ def OnSpinCtrl(self, event):
3396
+ """
3397
+ Handles the ``wx.EVT_SPINCTRL`` event for RGB and HSB colours.
3398
+
3399
+ :param `event`: a :class:`SpinEvent` event to be processed.
3400
+ """
3401
+
3402
+ obj = event.GetEventObject()
3403
+ position = self.spinCtrls.index(obj)
3404
+ colourVal = event.GetInt()
3405
+
3406
+ attribute, maxVal = colourAttributes[position], colourMaxValues[position]
3407
+
3408
+ self.AssignColourValue(attribute, colourVal, maxVal, position)
3409
+
3410
+
3411
+ def OnAlphaSpin(self, event):
3412
+ """
3413
+ Handles the ``wx.EVT_SPINCTRL`` event for the alpha channel.
3414
+
3415
+ :param `event`: a :class:`SpinEvent` event to be processed.
3416
+ """
3417
+
3418
+ colourVal = event.GetInt()
3419
+ originalVal = self._colour._alpha
3420
+ if colourVal != originalVal and self._initOver:
3421
+ if colourVal < 0:
3422
+ colourVal = 0
3423
+ if colourVal > 255:
3424
+ colourVal = 255
3425
+
3426
+ self._colour._alpha = colourVal
3427
+ self.DrawAlpha()
3428
+
3429
+
3430
+ def AssignColourValue(self, attribute, colourVal, maxVal, position):
3431
+ """ Common code to handle spin control changes. """
3432
+
3433
+ originalVal = getattr(self._colour, attribute)
3434
+ if colourVal != originalVal and self._initOver:
3435
+
3436
+ if colourVal < 0:
3437
+ colourVal = 0
3438
+ if colourVal > maxVal:
3439
+ colourVal = maxVal
3440
+
3441
+ setattr(self._colour, attribute, colourVal)
3442
+ if position < 3:
3443
+ self._colour.ToHSV()
3444
+ else:
3445
+ self._colour.ToRGB()
3446
+
3447
+ self.DrawAll()
3448
+
3449
+
3450
+ def DrawAll(self):
3451
+ """ Draws all the custom controls after a colour change. """
3452
+
3453
+ if self._initOver and not self._inDrawAll:
3454
+ self._inDrawAll = True
3455
+
3456
+ dc1 = wx.ClientDC(self.hsvBitmap)
3457
+ self.hsvBitmap.DrawMarkers(dc1)
3458
+
3459
+ dc2 = wx.ClientDC(self.rgbBitmap)
3460
+ self.rgbBitmap.DrawMarkers(dc2)
3461
+ self.rgbBitmap.DrawLines(dc2)
3462
+
3463
+ dc3 = wx.ClientDC(self.brightCtrl)
3464
+ self.brightCtrl.DrawMarkers(dc3)
3465
+
3466
+ dc4 = wx.ClientDC(self.alphaCtrl)
3467
+ self.alphaCtrl.DrawMarkers(dc4)
3468
+
3469
+ self.CalcCuboid()
3470
+ self.CalcRects()
3471
+
3472
+ self.DrawRGB()
3473
+ self.DrawHSB()
3474
+ self.DrawBright()
3475
+ self.DrawAlpha()
3476
+
3477
+ self.SetSpinVals()
3478
+ self._inDrawAll = False
3479
+
3480
+
3481
+ def GetColourData(self):
3482
+ """ Returns a wxPython compatible :class:`wx.ColourData`. """
3483
+
3484
+ self._colourData.SetColour(self._colour.GetPyColour())
3485
+ return self._colourData
3486
+
3487
+
3488
+ def GetRGBAColour(self):
3489
+ """ Returns a 4-elements tuple of red, green, blue, alpha components. """
3490
+
3491
+ return (self._colour.r, self._colour.g, self._colour.b, self._colour._alpha)
3492
+
3493
+
3494
+ def GetHSVAColour(self):
3495
+ """ Returns a 4-elements tuple of hue, saturation, brightness, alpha components. """
3496
+
3497
+ return (self._colour.h, self._colour.s, self._colour.v, self._colour._alpha)
3498
+
3499
+
3500
+ if __name__ == '__main__':
3501
+
3502
+ import wx
3503
+
3504
+ # Our normal wxApp-derived class, as usual
3505
+ app = wx.App(0)
3506
+
3507
+ colourData = wx.ColourData()
3508
+ colourData.SetColour(wx.SystemSettings.GetColour(wx.SYS_COLOUR_3DFACE))
3509
+ dlg = CubeColourDialog(None, colourData)
3510
+
3511
+ if dlg.ShowModal() == wx.ID_OK:
3512
+
3513
+ # If the user selected OK, then the dialog's wx.ColourData will
3514
+ # contain valid information. Fetch the data ...
3515
+ colourData = dlg.GetColourData()
3516
+ h, s, v, a = dlg.GetHSVAColour()
3517
+
3518
+ # ... then do something with it. The actual colour data will be
3519
+ # returned as a three-tuple (r, g, b) in this particular case.
3520
+ colour = colourData.GetColour()
3521
+ r, g, b, alpha = colour.Red(), colour.Green(), colour.Blue(), colour.Alpha()
3522
+ print(("You selected (RGBA): %d, %d, %d, %d"%(r, g, b, alpha)))
3523
+ print(("You selected (HSVA): %d, %d, %d, %d"%(h, s, v, a)))
3524
+
3525
+ # Once the dialog is destroyed, Mr. wx.ColourData is no longer your
3526
+ # friend. Don't use it again!
3527
+ dlg.Destroy()
3528
+
3529
+ app.MainLoop()