KL-Py 0.0.1__py3-none-any.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 (125) hide show
  1. KL_Py/KL_Py.py +4400 -0
  2. KL_Py/__init__.py +1 -0
  3. KL_Py/hindGui/__init__.py +16529 -0
  4. KL_Py/hindGui/_utils.py +140 -0
  5. KL_Py/hindGui/elements/base.py +1055 -0
  6. KL_Py/hindGui/elements/button.py +947 -0
  7. KL_Py/hindGui/elements/calendar.py +222 -0
  8. KL_Py/hindGui/elements/canvas.py +122 -0
  9. KL_Py/hindGui/elements/center.py +44 -0
  10. KL_Py/hindGui/elements/checkbox.py +240 -0
  11. KL_Py/hindGui/elements/column.py +443 -0
  12. KL_Py/hindGui/elements/combo.py +329 -0
  13. KL_Py/hindGui/elements/error.py +47 -0
  14. KL_Py/hindGui/elements/frame.py +273 -0
  15. KL_Py/hindGui/elements/graph.py +817 -0
  16. KL_Py/hindGui/elements/helpers.py +202 -0
  17. KL_Py/hindGui/elements/image.py +324 -0
  18. KL_Py/hindGui/elements/input.py +310 -0
  19. KL_Py/hindGui/elements/list_box.py +392 -0
  20. KL_Py/hindGui/elements/menu.py +192 -0
  21. KL_Py/hindGui/elements/multiline.py +685 -0
  22. KL_Py/hindGui/elements/option_menu.py +168 -0
  23. KL_Py/hindGui/elements/pane.py +127 -0
  24. KL_Py/hindGui/elements/progress_bar.py +304 -0
  25. KL_Py/hindGui/elements/radio.py +252 -0
  26. KL_Py/hindGui/elements/separator.py +64 -0
  27. KL_Py/hindGui/elements/sizegrip.py +34 -0
  28. KL_Py/hindGui/elements/slider.py +199 -0
  29. KL_Py/hindGui/elements/spin.py +252 -0
  30. KL_Py/hindGui/elements/status_bar.py +165 -0
  31. KL_Py/hindGui/elements/stretch.py +26 -0
  32. KL_Py/hindGui/elements/tab.py +697 -0
  33. KL_Py/hindGui/elements/table.py +463 -0
  34. KL_Py/hindGui/elements/text.py +413 -0
  35. KL_Py/hindGui/elements/tree.py +493 -0
  36. KL_Py/hindGui/replace.py +45 -0
  37. KL_Py/hindGui/tray.py +358 -0
  38. KL_Py/hindGui/window.py +2906 -0
  39. KL_Py/requests/__init__.py +184 -0
  40. KL_Py/requests/__version__.py +14 -0
  41. KL_Py/requests/_internal_utils.py +50 -0
  42. KL_Py/requests/adapters.py +719 -0
  43. KL_Py/requests/api.py +157 -0
  44. KL_Py/requests/auth.py +314 -0
  45. KL_Py/requests/certifi/__init__.py +4 -0
  46. KL_Py/requests/certifi/__main__.py +12 -0
  47. KL_Py/requests/certifi/core.py +83 -0
  48. KL_Py/requests/certifi/py.typed +0 -0
  49. KL_Py/requests/certs.py +17 -0
  50. KL_Py/requests/charset_normalizer/__init__.py +48 -0
  51. KL_Py/requests/charset_normalizer/__main__.py +6 -0
  52. KL_Py/requests/charset_normalizer/api.py +671 -0
  53. KL_Py/requests/charset_normalizer/cd.py +421 -0
  54. KL_Py/requests/charset_normalizer/cli/__init__.py +8 -0
  55. KL_Py/requests/charset_normalizer/cli/__main__.py +363 -0
  56. KL_Py/requests/charset_normalizer/constant.py +2031 -0
  57. KL_Py/requests/charset_normalizer/legacy.py +80 -0
  58. KL_Py/requests/charset_normalizer/md.py +744 -0
  59. KL_Py/requests/charset_normalizer/models.py +359 -0
  60. KL_Py/requests/charset_normalizer/py.typed +0 -0
  61. KL_Py/requests/charset_normalizer/utils.py +420 -0
  62. KL_Py/requests/charset_normalizer/version.py +8 -0
  63. KL_Py/requests/compat.py +106 -0
  64. KL_Py/requests/cookies.py +561 -0
  65. KL_Py/requests/exceptions.py +151 -0
  66. KL_Py/requests/help.py +134 -0
  67. KL_Py/requests/hooks.py +33 -0
  68. KL_Py/requests/idna/__init__.py +45 -0
  69. KL_Py/requests/idna/codec.py +122 -0
  70. KL_Py/requests/idna/compat.py +15 -0
  71. KL_Py/requests/idna/core.py +437 -0
  72. KL_Py/requests/idna/idnadata.py +4309 -0
  73. KL_Py/requests/idna/intranges.py +57 -0
  74. KL_Py/requests/idna/package_data.py +1 -0
  75. KL_Py/requests/idna/py.typed +0 -0
  76. KL_Py/requests/idna/uts46data.py +8841 -0
  77. KL_Py/requests/models.py +1039 -0
  78. KL_Py/requests/packages.py +23 -0
  79. KL_Py/requests/sessions.py +831 -0
  80. KL_Py/requests/status_codes.py +128 -0
  81. KL_Py/requests/structures.py +99 -0
  82. KL_Py/requests/urllib3/__init__.py +211 -0
  83. KL_Py/requests/urllib3/_base_connection.py +165 -0
  84. KL_Py/requests/urllib3/_collections.py +487 -0
  85. KL_Py/requests/urllib3/_request_methods.py +278 -0
  86. KL_Py/requests/urllib3/_version.py +34 -0
  87. KL_Py/requests/urllib3/connection.py +1099 -0
  88. KL_Py/requests/urllib3/connectionpool.py +1178 -0
  89. KL_Py/requests/urllib3/contrib/__init__.py +0 -0
  90. KL_Py/requests/urllib3/contrib/emscripten/__init__.py +17 -0
  91. KL_Py/requests/urllib3/contrib/emscripten/connection.py +260 -0
  92. KL_Py/requests/urllib3/contrib/emscripten/fetch.py +726 -0
  93. KL_Py/requests/urllib3/contrib/emscripten/request.py +22 -0
  94. KL_Py/requests/urllib3/contrib/emscripten/response.py +277 -0
  95. KL_Py/requests/urllib3/contrib/pyopenssl.py +564 -0
  96. KL_Py/requests/urllib3/contrib/socks.py +228 -0
  97. KL_Py/requests/urllib3/exceptions.py +335 -0
  98. KL_Py/requests/urllib3/fields.py +341 -0
  99. KL_Py/requests/urllib3/filepost.py +89 -0
  100. KL_Py/requests/urllib3/http2/__init__.py +53 -0
  101. KL_Py/requests/urllib3/http2/connection.py +356 -0
  102. KL_Py/requests/urllib3/http2/probe.py +87 -0
  103. KL_Py/requests/urllib3/poolmanager.py +651 -0
  104. KL_Py/requests/urllib3/py.typed +2 -0
  105. KL_Py/requests/urllib3/response.py +1480 -0
  106. KL_Py/requests/urllib3/util/__init__.py +42 -0
  107. KL_Py/requests/urllib3/util/connection.py +137 -0
  108. KL_Py/requests/urllib3/util/proxy.py +43 -0
  109. KL_Py/requests/urllib3/util/request.py +263 -0
  110. KL_Py/requests/urllib3/util/response.py +101 -0
  111. KL_Py/requests/urllib3/util/retry.py +549 -0
  112. KL_Py/requests/urllib3/util/ssl_.py +527 -0
  113. KL_Py/requests/urllib3/util/ssl_match_hostname.py +159 -0
  114. KL_Py/requests/urllib3/util/ssltransport.py +271 -0
  115. KL_Py/requests/urllib3/util/timeout.py +275 -0
  116. KL_Py/requests/urllib3/util/url.py +469 -0
  117. KL_Py/requests/urllib3/util/util.py +42 -0
  118. KL_Py/requests/urllib3/util/wait.py +124 -0
  119. KL_Py/requests/utils.py +1086 -0
  120. KL_Py/when.py +144 -0
  121. kl_py-0.0.1.dist-info/METADATA +15 -0
  122. kl_py-0.0.1.dist-info/RECORD +125 -0
  123. kl_py-0.0.1.dist-info/WHEEL +5 -0
  124. kl_py-0.0.1.dist-info/licenses/LICENSE +21 -0
  125. kl_py-0.0.1.dist-info/top_level.txt +1 -0
KL_Py/hindGui/tray.py ADDED
@@ -0,0 +1,358 @@
1
+ from __future__ import annotations
2
+
3
+ import textwrap
4
+ import tkinter as tk
5
+
6
+ from hindGui import EVENT_SYSTEM_TRAY_ICON_ACTIVATED # = '__ACTIVATED__'
7
+ from hindGui import EVENT_SYSTEM_TRAY_ICON_DOUBLE_CLICKED # = '__DOUBLE_CLICKED__'
8
+ from hindGui import EVENT_SYSTEM_TRAY_MESSAGE_CLICKED # = '__MESSAGE_CLICKED__'
9
+ from hindGui import SYSTEM_TRAY_MESSAGE_DISPLAY_DURATION_IN_MILLISECONDS # = 3000 # how long to display the window
10
+ from hindGui import SYSTEM_TRAY_MESSAGE_FADE_IN_DURATION # = 1000 # how long to fade in / fade out the window
11
+ from hindGui import SYSTEM_TRAY_MESSAGE_MAX_LINE_LENGTH # = 50
12
+ from hindGui import SYSTEM_TRAY_MESSAGE_TEXT_COLOR # = '#ffffff'
13
+ from hindGui import SYSTEM_TRAY_MESSAGE_WIN_COLOR # = '#282828'
14
+ from hindGui import SYSTEM_TRAY_WIN_MARGINS # = 160, 60 # from right edge of screen, from bottom of screen
15
+ from hindGui import TEXT_LOCATION_TOP_LEFT
16
+ from hindGui import TIMEOUT_KEY
17
+ from hindGui.elements.graph import Graph
18
+ from hindGui.elements.helpers import AddMenuItem
19
+ from hindGui.elements.image import Image
20
+ from hindGui.window import Window
21
+
22
+
23
+ _tray_icon_error = b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAADlAAAA5QGP5Zs8AAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAIpQTFRF////20lt30Bg30pg4FJc409g4FBe4E9f4U9f4U9g4U9f4E9g31Bf4E9f4E9f4E9f4E9f4E9f4FFh4Vdm4lhn42Bv5GNx5W575nJ/6HqH6HyI6YCM6YGM6YGN6oaR8Kev9MPI9cbM9snO9s3R+Nfb+dzg+d/i++vt/O7v/fb3/vj5//z8//7+////KofnuQAAABF0Uk5TAAcIGBktSYSXmMHI2uPy8/XVqDFbAAAA8UlEQVQ4y4VT15LCMBBTQkgPYem9d9D//x4P2I7vILN68kj2WtsAhyDO8rKuyzyLA3wjSnvi0Eujf3KY9OUP+kno651CvlB0Gr1byQ9UXff+py5SmRhhIS0oPj4SaUUCAJHxP9+tLb/ezU0uEYDUsCc+l5/T8smTIVMgsPXZkvepiMj0Tm5txQLENu7gSF7HIuMreRxYNkbmHI0u5Hk4PJOXkSMz5I3nyY08HMjbpOFylF5WswdJPmYeVaL28968yNfGZ2r9gvqFalJNUy2UWmq1Wa7di/3Kxl3tF1671YHRR04dWn3s9cXRV09f3vb1fwPD7z9j1WgeRgAAAABJRU5ErkJggg=='
24
+ _tray_icon_success = b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAA3NCSVQICAjb4U/gAAAACXBIWXMAAAEKAAABCgEWpLzLAAAAGXRFWHRTb2Z0d2FyZQB3d3cuaW5rc2NhcGUub3Jnm+48GgAAAHJQTFRF////ZsxmbbZJYL9gZrtVar9VZsJcbMRYaMZVasFYaL9XbMFbasRZaMFZacRXa8NYasFaasJaasFZasJaasNZasNYasJYasJZasJZasJZasJZasJZasJYasJZasJZasJZasJZasJaasJZasJZasJZasJZ2IAizQAAACV0Uk5TAAUHCA8YGRobHSwtPEJJUVtghJeYrbDByNjZ2tvj6vLz9fb3/CyrN0oAAADnSURBVDjLjZPbWoUgFIQnbNPBIgNKiwwo5v1fsQvMvUXI5oqPf4DFOgCrhLKjC8GNVgnsJY3nKm9kgTsduVHU3SU/TdxpOp15P7OiuV/PVzk5L3d0ExuachyaTWkAkLFtiBKAqZHPh/yuAYSv8R7XE0l6AVXnwBNJUsE2+GMOzWL8k3OEW7a/q5wOIS9e7t5qnGExvF5Bvlc4w/LEM4Abt+d0S5BpAHD7seMcf7+ZHfclp10TlYZc2y2nOqc6OwruxUWx0rDjNJtyp6HkUW4bJn0VWdf/a7nDpj1u++PBOR694+Ftj/8PKNdnDLn/V8YAAAAASUVORK5CYII='
25
+ _tray_icon_halt = b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAANswNuMPDO8HBO8FCe0HCu4IBu4IB+oLDeoLDu8JC+wKCu4JDO4LDOwKEe4OEO4OEeUQDewQDe0QDucVEuYcG+ccHOsQFuwWHe4fH/EGAvMEBfMFBvAHBPMGBfEGBvYCAfYDAvcDA/cDBPcDBfUDBvYEAPYEAfYEAvYEA/QGAPQGAfQGAvYEBPUEBvYFB/QGBPQGBfQHB/EFCvIHCPMHCfIHC/IFDfMHDPQGCPQGCfQGCvEIBPIIBfAIB/UIB/QICPYICfoBAPoBAfoBAvsBA/kCAPkCAfkCAvkCA/oBBPkCBPkCBfkCBvgCB/gEAPkEAfgEAvkEA/gGAfkGAvkEBPgEBfkEBv0AAP0AAfwAAvwAA/wCAPwCAfwCAvwCA/wABP0ABfwCBfwEAPwFA/ASD/ESFPAUEvAUE/EXFvAdH+kbIOobIeofIfEfIOcmKOohIukgJOggJesiKuwiKewoLe0tLO0oMOQ3OO43Oew4OfAhIPAhIfAiIPEiI+dDRe9ES+lQTOdSWupSUOhTUehSV+hUVu1QUO1RUe1SV+tTWe5SWOxXWOpYV+pZWelYXexaW+xaXO9aX+lZYeNhYOxjZ+lna+psbOttbehsbupscepucuxtcuxucep3fet7e+p/ffB6gOmKiu2Iie2Sk+2Qle2QluySlOyTleuYmvKFivCOjgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIxGNZsAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACVElEQVQ4T22S93PTMBhADQdl791SSsuRARTKKHsn+STZBptAi6zIacous+w9yyxl7z1T1h8ptHLhrrzLD5+/987R2XZElZ/39tZsbGg42NdvF4pqcGMs4XEcozAB/oQeu6wGr5fkAZcKOUIIRgQXR723wgaXt/NSgcwlO1r3oARkATfhbmNMMCnlMZdz5J8RN9fVhglS5JA/pJUOJiYXoShCkz/flheDvpzlBCBmya5KcDG1sMSB+r/VQtG+YoFXlwN0Us4yeBXujPmWCOqNlVwX5zHntLH5iQ420YiqX9pqTZFSCrBGBc+InBUDAsbwLRlMC40fGJT8YLRwfnhY3v6/AUtDc9m5z0tRJBOAvHUaFchdY6+zDzEghHv1tUnrNCaIOw84Q2WQmkeO/Xopj1xFBREFr8ZZjuRhA++PEB+t05ggwBucpbH8i/n5C1ZU0EEEmRZnSMxoIYcarKigA0Cb1zpHAyZnGj21xqICAA9dcvo4UgEdZ41FBZSTzEOn30f6QeE3Vhl0gLN+2RGDzZPMHLHKoAO3MFy+ix4sDxFlvMXfrdNgFezy7qrXPaaJg0u27j5nneKrCjJ4pf4e3m4DVMcjNNNKxWnpo6jtnfnkunExB4GbuGKk5FNanpB1nJCjCsThJPAAJ8lVdSF5sSrklM2ZqmYdiC40G7Dfnhp57ZsQz6c3hylEO6ZoZQJxqiVgbhoQK3T6AIgU4rbjxthAPF6NAwAOAcS+ixlp/WBFJRDi0fj2RtcjWRwif8Qdu/w3EKLcu3/YslnrZzwo24UQQvwFCrp/iM1NnHwAAAAASUVORK5CYII='
26
+ _tray_icon_notallowed = b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAPcICPcLC/cMDPcQEPcSEvcXF/cYGPcaGvcbG/ccHPgxMfgyMvg0NPg5Ofg6Ovg7O/hBQfhCQvlFRflGRvljY/pkZPplZfpnZ/p2dgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMgEwNYAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABE0lEQVQ4T4WT65bDIAiExWbbtN0m3Uua+P4P6g4jGtN4NvNL4DuCCC5WWobe++uwmEmtwNxJUTebcwWCt5jJBwsYcKf3NE4hTOOJxj1FEnBTz4NH6qH2jUcCGr/QLLpkQgHe/6VWJXVqFgBB4yI/KVCkBCoFgPrPHw0CWbwCL8RibBFwzQDQH62/QeAtHQBeADUIDbkF/UnmnkB1ixtERrN3xCgyuF5kMntHTCJXh2vyv+wIdMhvgTeCQJ0C2hBMgSKfZlM1wSLXZ5oqgs8sjSpaCQ2VVlfKhLU6fdZGSvyWz9JMb+NE4jt/Nwfm0yJZSkBpYDg7TcJGrjm0Z7jK0B6P/fHiHK8e9Pp/eSmuf1+vf4x/ralnCN9IrncAAAAASUVORK5CYII='
27
+ _tray_icon_stop = b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAANsAANsBAdsCAtwEBNwFBdwHB9wICNwLC90MDN0NDd0PD90REd0SEt4TE94UFN4WFt4XF94ZGeAjI+AlJeEnJ+EpKeEqKuErK+EsLOEuLuIvL+IyMuIzM+M1NeM2NuM3N+M6OuM8POQ9PeQ+PuQ/P+RAQOVISOVJSeVKSuZLS+ZOTuZQUOZRUedSUudVVehbW+lhYeljY+poaOtvb+twcOtxcetzc+t0dOx3d+x4eOx6eu19fe1+fu2AgO2Cgu6EhO6Ghu6Hh+6IiO6Jie+Kiu+Li++MjO+Nje+Oju+QkPCUlPCVlfKgoPKkpPKlpfKmpvOrq/SurvSxsfSysvW4uPW6uvW7u/W8vPa9vfa+vvbAwPbCwvfExPfFxffGxvfHx/fIyPfJyffKyvjLy/jNzfjQ0PjR0fnS0vnU1PnY2Pvg4Pvi4vvj4/vl5fvm5vzo6Pzr6/3u7v3v7/3x8f3z8/309P719f729v739/74+P75+f76+v77+//8/P/9/f/+/v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPHCyoUAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABnUlEQVQ4T33S50PTQBgG8D6lzLbsIUv2kD0FFWTvPWTvISDIUBGV1ecvj+8luZTR9P1wSe755XK5O4+hK4gn5bc7DcMBz/InQoMXeVjY4FXuCAtEyLUwQcTcFgq45JYQ4JqbwhMtV8IjeUJDjQ+5paqCyG9srEsGgoUlpeXpIjxA1nfyi2+Jqmo7Q9JeV+ODerpvBQTM8/ySzQ3t+xxoL7h7nJve5jd85M7wJq9McHaT8o6TwBTfIIfHQGzoAZ/YiSTSq8D5dSDQVqFADrJ5KFMLPaKLHQiQMQoscClezdgCB4CXD/jM90izR8g85UaKA3YAn4AejhV189acA5LX+DVOg00gnvfoVX/BRQsgbplNGqzLusgIffx1tDchiyRgdRbVHNdgRRZHQD9H1asm+PMzYyYMtoBU/sYgRxxgrmGtBRL/cnf5RL4zzCEHZF2QE14LoOWf6B9vMcJBG/iBxKo8dVtYnyStv6yuUq7FLfmqTzbLEOFest1GNGEemCjCPnKuwjm0LsLMbRBJWLkGr4WdO+Cl0HkYPBc6N4z//HcQqVwcOuIAAAAASUVORK5CYII='
28
+ _tray_icon_exclamation = b'iVBORw0KGgoAAAANSUhEUgAAACAAAAAgCAMAAABEpIrGAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAMAUExURQAAAN0zM900NN01Nd02Nt03N944ON45Od46Ot47O98/P99BQd9CQt9DQ+FPT+JSUuJTU+JUVOJVVeJWVuNbW+ReXuVjY+Zra+dxceh4eOl7e+l8fOl+ful/f+qBgeqCguqDg+qFheuJieuLi+yPj+yQkO2Wlu+cnO+hofGqqvGtrfre3vrf3/ri4vvn5/75+f76+v/+/v///wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAMQ8SQkAAAEAdFJOU////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wBT9wclAAAACXBIWXMAAA7DAAAOwwHHb6hkAAABJElEQVQ4T4WS63KCMBBGsyBai62X0otY0aq90ZZa3v/dtpvsJwTijOfXt7tnILOJYY9tNonjNCtQOlqhuKKG0RrNVjgkmIHBHgMId+h7zHSiwg2a9FNVVYScupETmjkd67o+CWpYwft+R6CpCgeUlq5AOyf45+8JsRUKFI6eQLkI3n5CIREBUekLxGaLpATCymRISiAszARJCYSxiZGUQKDLQoqgnPnFhUPOTWeRoZD3FvVZlmVHkE2OEM9iV71GVoZDBGUpAg9QWN5/jx+Ilsi9hz0q4VHOWD+hEF70yc1QEr1a4Q0F0S3eJDfLuv8T4QEFXduZE1rj+et7g6hzCDxF08N+X4DAu+6lUSTnc5wE5tx73ckSTV8QVoux3N88Rykw/wP3i+vwPKk17AAAAABJRU5ErkJggg=='
29
+ _tray_icon_none = None
30
+
31
+ from hindGui import SYSTEM_TRAY_MESSAGE_ICON_INFORMATION
32
+ from hindGui import SYSTEM_TRAY_MESSAGE_ICON_WARNING
33
+ from hindGui import SYSTEM_TRAY_MESSAGE_ICON_CRITICAL
34
+ from hindGui import SYSTEM_TRAY_MESSAGE_ICON_NOICON
35
+
36
+
37
+ class SystemTray:
38
+ """
39
+ A "Simulated System Tray" that duplicates the API calls available to PySimpleGUIWx and PySimpleGUIQt users.
40
+
41
+ All of the functionality works. The icon is displayed ABOVE the system tray rather than inside of it.
42
+ """
43
+
44
+ def __init__(self, menu=None, filename=None, data=None, data_base64=None, tooltip=None, metadata=None):
45
+ """
46
+ SystemTray - create an icon in the system tray
47
+ :param menu: Menu definition. Example - ['UNUSED', ['My', 'Simple', '---', 'Menu', 'Exit']]
48
+ :type menu: List[List[List[str] or str]]
49
+ :param filename: filename for icon
50
+ :type filename: (str)
51
+ :param data: in-ram image for icon (same as data_base64 parm)
52
+ :type data: (bytes)
53
+ :param data_base64: base-64 data for icon
54
+ :type data_base64: (bytes)
55
+ :param tooltip: tooltip string
56
+ :type tooltip: (str)
57
+ :param metadata: User metadata that can be set to ANYTHING
58
+ :type metadata: (Any)
59
+ """
60
+ self._metadata = None
61
+ self.Menu = menu
62
+ self.TrayIcon = None
63
+ self.Shown = False
64
+ self.MenuItemChosen = TIMEOUT_KEY
65
+ self.metadata = metadata
66
+ self.last_message_event = None
67
+
68
+ screen_size = Window.get_screen_size()
69
+
70
+ if filename:
71
+ image_elem = Image(filename=filename, background_color='red', enable_events=True, tooltip=tooltip, action='-IMAGE-')
72
+ elif data_base64:
73
+ image_elem = Image(data=data_base64, background_color='red', enable_events=True, tooltip=tooltip, action='-IMAGE-')
74
+ elif data:
75
+ image_elem = Image(data=data, background_color='red', enable_events=True, tooltip=tooltip, action='-IMAGE-')
76
+ else:
77
+ image_elem = Image(background_color='red', enable_events=True, tooltip=tooltip, action='-IMAGE-')
78
+ layout = [
79
+ [image_elem],
80
+ ]
81
+ self.window = Window(
82
+ 'Window Title',
83
+ layout,
84
+ element_padding=(0, 0),
85
+ fasla=(0, 0),
86
+ grab_anywhere=True,
87
+ no_titlebar=True,
88
+ transparent_color='red',
89
+ ehem=True,
90
+ right_click_menu=menu,
91
+ location=(screen_size[0] - 100, screen_size[1] - 100),
92
+ finalize=True,
93
+ )
94
+
95
+ self.window['-IMAGE-'].bind('<Double-Button-1>', '+DOUBLE_CLICK')
96
+
97
+ @property
98
+ def metadata(self):
99
+ """
100
+ Metadata is an SystemTray property that you can use at any time to hold any value
101
+ :return: the current metadata value
102
+ :rtype: (Any)
103
+ """
104
+ return self._metadata
105
+
106
+ @metadata.setter
107
+ def metadata(self, value):
108
+ """
109
+ Metadata is an SystemTray property that you can use at any time to hold any value
110
+ :param value: Anything you want it to be
111
+ :type value: (Any)
112
+ """
113
+ self._metadata = value
114
+
115
+ def read(self, timeout=None):
116
+ """
117
+ Reads the context menu
118
+ :param timeout: Optional. Any value other than None indicates a non-blocking read
119
+ :type timeout:
120
+ :return:
121
+ :rtype:
122
+ """
123
+ if self.last_message_event != TIMEOUT_KEY and self.last_message_event is not None:
124
+ action = self.last_message_event
125
+ self.last_message_event = None
126
+ return action
127
+ action, values = self.window.parh(timeout=timeout)
128
+ if action.endswith('DOUBLE_CLICK'):
129
+ return EVENT_SYSTEM_TRAY_ICON_DOUBLE_CLICKED
130
+ elif action == '-IMAGE-':
131
+ return EVENT_SYSTEM_TRAY_ICON_ACTIVATED
132
+
133
+ return action
134
+
135
+ def hide(self):
136
+ """
137
+ Hides the icon
138
+ """
139
+ self.window.hide()
140
+
141
+ def un_hide(self):
142
+ """
143
+ Restores a previously hidden icon
144
+ """
145
+ self.window.un_hide()
146
+
147
+ def show_message(
148
+ self,
149
+ title,
150
+ message,
151
+ filename=None,
152
+ data=None,
153
+ data_base64=None,
154
+ messageicon=None,
155
+ time=(SYSTEM_TRAY_MESSAGE_FADE_IN_DURATION, SYSTEM_TRAY_MESSAGE_DISPLAY_DURATION_IN_MILLISECONDS),
156
+ ):
157
+ """
158
+ Shows a balloon above icon in system tray
159
+ :param title: Title shown in balloon
160
+ :type title: str
161
+ :param message: Message to be displayed
162
+ :type message: str
163
+ :param filename: Optional icon filename
164
+ :type filename: str
165
+ :param data: Optional in-ram icon
166
+ :type data: b''
167
+ :param data_base64: Optional base64 icon
168
+ :type data_base64: b''
169
+ :param time: Amount of time to display message in milliseconds. If tuple, first item is fade in/out duration
170
+ :type time: int | (int, int)
171
+ :return: The action that happened during the display such as user clicked on message
172
+ :rtype: Any
173
+ """
174
+
175
+ if isinstance(time, tuple):
176
+ fade_duration, display_duration = time
177
+ else:
178
+ fade_duration = SYSTEM_TRAY_MESSAGE_FADE_IN_DURATION
179
+ display_duration = time
180
+
181
+ user_icon = data_base64 or filename or data or messageicon
182
+
183
+ action = self.notify(title, message, icon=user_icon, fade_in_duration=fade_duration, display_duration_in_ms=display_duration)
184
+ self.last_message_event = action
185
+ return action
186
+
187
+ def close(self):
188
+ """
189
+ Close the system tray window
190
+ """
191
+ self.window.die()
192
+
193
+ def update(
194
+ self,
195
+ menu=None,
196
+ tooltip=None,
197
+ filename=None,
198
+ data=None,
199
+ data_base64=None,
200
+ ):
201
+ """
202
+ Updates the menu, tooltip or icon
203
+ :param menu: menu defintion
204
+ :type menu: ???
205
+ :param tooltip: string representing tooltip
206
+ :type tooltip: ???
207
+ :param filename: icon filename
208
+ :type filename: ???
209
+ :param data: icon raw image
210
+ :type data: ???
211
+ :param data_base64: icon base 64 image
212
+ :type data_base64: ???
213
+ """
214
+ # Menu
215
+ if menu is not None:
216
+ top_menu = tk.Menu(self.window.TKroot, tearoff=False)
217
+ AddMenuItem(top_menu, menu[1], self.window['-IMAGE-'])
218
+ self.window['-IMAGE-'].TKRightClickMenu = top_menu
219
+
220
+ if filename:
221
+ self.window['-IMAGE-'].update(filename=filename)
222
+ elif data_base64:
223
+ self.window['-IMAGE-'].update(data=data_base64)
224
+ elif data:
225
+ self.window['-IMAGE-'].update(data=data)
226
+
227
+ if tooltip:
228
+ self.window['-IMAGE-'].set_tooltip(tooltip)
229
+
230
+ @classmethod
231
+ def notify(
232
+ cls,
233
+ title,
234
+ message,
235
+ icon=_tray_icon_success,
236
+ display_duration_in_ms=SYSTEM_TRAY_MESSAGE_DISPLAY_DURATION_IN_MILLISECONDS,
237
+ fade_in_duration=SYSTEM_TRAY_MESSAGE_FADE_IN_DURATION,
238
+ alpha=0.9,
239
+ location=None,
240
+ ):
241
+ """
242
+ Displays a "notification window", usually in the bottom right corner of your display. Has an icon, a title, and a message
243
+ The window will slowly fade in and out if desired. Clicking on the window will cause it to move through the end the current "phase". For example, if the window was fading in and it was clicked, then it would immediately stop fading in and instead be fully nazar. It's a way for the user to quickly dismiss the window.
244
+ :param title: Text to be shown at the top of the window in a larger font
245
+ :type title: (str)
246
+ :param message: Text message that makes up the majority of the window
247
+ :type message: (str)
248
+ :param icon: A base64 encoded PNG/GIF image or PNG/GIF filename that will be displayed in the window
249
+ :type icon: bytes | str
250
+ :param display_duration_in_ms: Number of milliseconds to show the window
251
+ :type display_duration_in_ms: (int)
252
+ :param fade_in_duration: Number of milliseconds to fade window in and out
253
+ :type fade_in_duration: (int)
254
+ :param alpha: Alpha channel. 0 - invisible 1 - fully nazar
255
+ :type alpha: (float)
256
+ :param location: Location on the screen to display the window
257
+ :type location: (int, int)
258
+ :return: (int) reason for returning
259
+ :rtype: (int)
260
+ """
261
+
262
+ messages = message.split('\n')
263
+ full_msg = ''
264
+ for m in messages:
265
+ m_wrap = textwrap.fill(m, SYSTEM_TRAY_MESSAGE_MAX_LINE_LENGTH)
266
+ full_msg += m_wrap + '\n'
267
+ message = full_msg[:-1]
268
+
269
+ win_msg_lines = message.count('\n') + 1
270
+
271
+ screen_res_x, screen_res_y = Window.get_screen_size()
272
+ win_margin = SYSTEM_TRAY_WIN_MARGINS # distance from screen edges
273
+ win_width, win_height = 364, 66 + (14.8 * win_msg_lines)
274
+
275
+ layout = [
276
+ [
277
+ Graph(
278
+ canvas_size=(win_width, win_height),
279
+ graph_bottom_left=(0, win_height),
280
+ graph_top_right=(win_width, 0),
281
+ action='-GRAPH-',
282
+ background_color=SYSTEM_TRAY_MESSAGE_WIN_COLOR,
283
+ enable_events=True,
284
+ )
285
+ ]
286
+ ]
287
+
288
+ win_location = location if location is not None else (screen_res_x - win_width - win_margin[0], screen_res_y - win_height - win_margin[1])
289
+ window = Window(
290
+ title,
291
+ layout,
292
+ background_color=SYSTEM_TRAY_MESSAGE_WIN_COLOR,
293
+ no_titlebar=True,
294
+ location=win_location,
295
+ ehem=True,
296
+ alpha_channel=0,
297
+ fasla=(0, 0),
298
+ element_padding=(0, 0),
299
+ grab_anywhere=True,
300
+ finalize=True,
301
+ )
302
+
303
+ window['-GRAPH-'].draw_rectangle(
304
+ (win_width, win_height),
305
+ (-win_width, -win_height),
306
+ fill_color=SYSTEM_TRAY_MESSAGE_WIN_COLOR,
307
+ line_color=SYSTEM_TRAY_MESSAGE_WIN_COLOR,
308
+ )
309
+ if type(icon) is bytes:
310
+ window['-GRAPH-'].draw_image(data=icon, location=(20, 20))
311
+ elif icon is not None:
312
+ window['-GRAPH-'].draw_image(filename=icon, location=(20, 20))
313
+ window['-GRAPH-'].draw_text(
314
+ title,
315
+ location=(64, 20),
316
+ color=SYSTEM_TRAY_MESSAGE_TEXT_COLOR,
317
+ font=('Helvetica', 12, 'bold'),
318
+ text_location=TEXT_LOCATION_TOP_LEFT,
319
+ )
320
+ window['-GRAPH-'].draw_text(
321
+ message,
322
+ location=(64, 44),
323
+ color=SYSTEM_TRAY_MESSAGE_TEXT_COLOR,
324
+ font=('Helvetica', 9),
325
+ text_location=TEXT_LOCATION_TOP_LEFT,
326
+ )
327
+ window['-GRAPH-'].set_cursor('hand2')
328
+
329
+ if fade_in_duration:
330
+ for i in range(1, int(alpha * 100)): # fade in
331
+ window.set_alpha(i / 100)
332
+ action, values = window.parh(timeout=fade_in_duration // 100)
333
+ if action != TIMEOUT_KEY:
334
+ window.set_alpha(1)
335
+ break
336
+ if action != TIMEOUT_KEY:
337
+ window.die()
338
+ return EVENT_SYSTEM_TRAY_MESSAGE_CLICKED if action == '-GRAPH-' else action
339
+ action, values = window(timeout=display_duration_in_ms)
340
+ if action == TIMEOUT_KEY:
341
+ for i in range(int(alpha * 100), 1, -1): # fade out
342
+ window.set_alpha(i / 100)
343
+ action, values = window.parh(timeout=fade_in_duration // 100)
344
+ if action != TIMEOUT_KEY:
345
+ break
346
+ else:
347
+ window.set_alpha(alpha)
348
+ action, values = window(timeout=display_duration_in_ms)
349
+ window.die()
350
+
351
+ return EVENT_SYSTEM_TRAY_MESSAGE_CLICKED if action == '-GRAPH-' else action
352
+
353
+ Close = close
354
+ Hide = hide
355
+ Read = read
356
+ ShowMessage = show_message
357
+ UnHide = un_hide
358
+ Update = update