ok-script 3.0.0b2__tar.gz → 3.0.0b3__tar.gz

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 (363) hide show
  1. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/PKG-INFO +1 -1
  2. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/MainWindow.py +3 -4
  3. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/__init__.py +2 -2
  4. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/feedback.py +43 -14
  5. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/icons.py +104 -3
  6. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/tabs.py +3 -2
  7. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/plugins/imported_tabs.py +1 -0
  8. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/shell/nav_icons.py +2 -2
  9. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/shell/run_bar.py +6 -4
  10. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/tasks_page.py +102 -28
  11. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok_script.egg-info/PKG-INFO +1 -1
  12. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_kit.py +74 -2
  13. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_shell.py +1 -1
  14. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_tasks_page.py +61 -0
  15. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/develop/SKILL.md +0 -0
  16. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/develop/agents/openai.yaml +0 -0
  17. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/develop/references/windows-input.md +0 -0
  18. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/generate-templates/SKILL.md +0 -0
  19. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/reload-tasks/SKILL.md +0 -0
  20. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/reload-tasks/agents/openai.yaml +0 -0
  21. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/setup-env/SKILL.md +0 -0
  22. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/setup-env/agents/openai.yaml +0 -0
  23. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/setup-env/assets/ok-script-develop/SKILL.md +0 -0
  24. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/setup-project/SKILL.md +0 -0
  25. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/setup-project/agents/openai.yaml +0 -0
  26. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/use_venv/SKILL.md +0 -0
  27. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/write-test/SKILL.md +0 -0
  28. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/.agents/skills/write-test/agents/openai.yaml +0 -0
  29. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/LICENSE.txt +0 -0
  30. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/MANIFEST.in +0 -0
  31. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/README.md +0 -0
  32. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/diagnostics/qq_trace.py +0 -0
  33. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/docs/agent-setup.md +0 -0
  34. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/docs/feature-crops.md +0 -0
  35. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/docs/mcp.md +0 -0
  36. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/examples/mcp_observe.py +0 -0
  37. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/__init__.py +0 -0
  38. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/__main__.py +0 -0
  39. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/alas/__init__.py +0 -0
  40. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/alas/emulator_base.py +0 -0
  41. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/alas/emulator_windows.py +0 -0
  42. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/alas/platform_windows.py +0 -0
  43. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/alas/utils.py +0 -0
  44. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/assets/default-icon.png +0 -0
  45. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/capture/__init__.py +0 -0
  46. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/capture/adb/__init__.py +0 -0
  47. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/capture/adb/deep.py +0 -0
  48. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/capture/adb/minitouch.py +0 -0
  49. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/capture/adb/nemu_ipc.py +0 -0
  50. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/capture/adb/nemu_utils.py +0 -0
  51. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/capture/adb/pool.py +0 -0
  52. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/capture/adb/timer.py +0 -0
  53. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/capture/adb/util.py +0 -0
  54. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/capture/windows/__init__.py +0 -0
  55. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/capture/windows/d3d11.py +0 -0
  56. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/capture/windows/dump.py +0 -0
  57. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/cli.py +0 -0
  58. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/__init__.py +0 -0
  59. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/capture_labels.py +0 -0
  60. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/code_runner.py +0 -0
  61. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/config_schema.py +0 -0
  62. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/downloads.py +0 -0
  63. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/events.py +0 -0
  64. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/icons.py +0 -0
  65. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/mcp_runner.py +0 -0
  66. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/mcp_server.py +0 -0
  67. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/notifications.py +0 -0
  68. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/plugin_staging.py +0 -0
  69. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/plugins.py +0 -0
  70. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/screenshot.py +0 -0
  71. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/script_editing.py +0 -0
  72. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/script_packager.py +0 -0
  73. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/script_templates.py +0 -0
  74. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/skills.py +0 -0
  75. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/start_controller.py +0 -0
  76. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/task_manager.py +0 -0
  77. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/template_store.py +0 -0
  78. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/translation.py +0 -0
  79. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/core/ui_config.py +0 -0
  80. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/DeviceManager.py +0 -0
  81. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/__init__.py +0 -0
  82. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture.py +0 -0
  83. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/__init__.py +0 -0
  84. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/adb.py +0 -0
  85. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/base.py +0 -0
  86. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/bitblt.py +0 -0
  87. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/bitblt_utils.py +0 -0
  88. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/browser.py +0 -0
  89. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/desktop_duplication.py +0 -0
  90. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/hwnd_window.py +0 -0
  91. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/image.py +0 -0
  92. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/nemu_ipc.py +0 -0
  93. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/types.py +0 -0
  94. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/update.py +0 -0
  95. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/windows_graphics.py +0 -0
  96. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/capture_methods/windows_graphics_hdr.py +0 -0
  97. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/interaction.py +0 -0
  98. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/interaction_methods/__init__.py +0 -0
  99. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/interaction_methods/adb.py +0 -0
  100. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/interaction_methods/base.py +0 -0
  101. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/interaction_methods/browser.py +0 -0
  102. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/interaction_methods/do_nothing.py +0 -0
  103. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/interaction_methods/foreground_post_message.py +0 -0
  104. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/interaction_methods/genshin.py +0 -0
  105. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/interaction_methods/keys.py +0 -0
  106. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/interaction_methods/post_message.py +0 -0
  107. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/interaction_methods/pydirect.py +0 -0
  108. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/interaction_methods/pynput.py +0 -0
  109. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/interaction_methods/swipe.py +0 -0
  110. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/device/intercation.py +0 -0
  111. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/feature/Box.py +0 -0
  112. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/feature/Feature.py +0 -0
  113. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/feature/FeatureSet.py +0 -0
  114. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/feature/__init__.py +0 -0
  115. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/gui/__init__.py +0 -0
  116. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/gui/util/pyappify_startup.py +0 -0
  117. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/notification/__init__.py +0 -0
  118. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/notification/manager.py +0 -0
  119. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/notification/messenger_images.py +0 -0
  120. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/notification/pipeline.py +0 -0
  121. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/notification/ppocr.py +0 -0
  122. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/notification/providers.py +0 -0
  123. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/notification/system.py +0 -0
  124. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/notification/windows_messenger.py +0 -0
  125. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ocr/__init__.py +0 -0
  126. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ocr/download_paddle_model.py +0 -0
  127. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Foundation/Collections.py +0 -0
  128. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Foundation/__init__.py +0 -0
  129. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Globalization/__init__.py +0 -0
  130. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Graphics/Capture/__init__.py +0 -0
  131. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Graphics/DirectX/Direct3D11/__init__.py +0 -0
  132. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Graphics/DirectX/__init__.py +0 -0
  133. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Graphics/Imaging/__init__.py +0 -0
  134. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Graphics/__init__.py +0 -0
  135. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Media/Ocr/__init__.py +0 -0
  136. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Media/__init__.py +0 -0
  137. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Security/Cryptography/__init__.py +0 -0
  138. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Security/__init__.py +0 -0
  139. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Storage/Streams/__init__.py +0 -0
  140. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/Storage/__init__.py +0 -0
  141. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/UI/ViewManagement/__init__.py +0 -0
  142. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/UI/__init__.py +0 -0
  143. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/Windows/__init__.py +0 -0
  144. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/__init__.py +0 -0
  145. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/delegate.py +0 -0
  146. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/export.py +0 -0
  147. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/idldsl.py +0 -0
  148. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/inspectable.py +0 -0
  149. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/roapi.py +0 -0
  150. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/types.py +0 -0
  151. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/rotypes/winstring.py +0 -0
  152. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/task/DiagnosisTask.py +0 -0
  153. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/task/TaskExecutor.py +0 -0
  154. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/task/__init__.py +0 -0
  155. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/task/exceptions.py +0 -0
  156. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/task/task.py +0 -0
  157. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/test/OKTestRunner.py +0 -0
  158. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/test/RunTests.py +0 -0
  159. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/test/TaskTestCase.py +0 -0
  160. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/test/__init__.py +0 -0
  161. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/third_party/__init__.py +0 -0
  162. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/third_party/paperclip.py +0 -0
  163. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/__init__.py +0 -0
  164. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/overlay/__init__.py +0 -0
  165. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/overlay/win32_gdi.py +0 -0
  166. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/Communicate.py +0 -0
  167. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/MessageWindow.py +0 -0
  168. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/StartController.py +0 -0
  169. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/__init__.py +0 -0
  170. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/about/AboutTab.py +0 -0
  171. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/about/UpdateCard.py +0 -0
  172. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/about/__init__.py +0 -0
  173. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/common/__init__.py +0 -0
  174. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/common/config.py +0 -0
  175. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/debug/OverlayWidget.py +0 -0
  176. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/debug/Screenshot.py +0 -0
  177. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/debug/__init__.py +0 -0
  178. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/debug/diagnosis_page.py +0 -0
  179. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/events.py +0 -0
  180. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/GettextTranslator.py +0 -0
  181. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/__init__.py +0 -0
  182. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/en_US.qm +0 -0
  183. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/en_US.ts +0 -0
  184. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/es_ES.qm +0 -0
  185. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/es_ES.ts +0 -0
  186. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/ja_JP.qm +0 -0
  187. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/ja_JP.ts +0 -0
  188. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/ko_KR.qm +0 -0
  189. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/ko_KR.ts +0 -0
  190. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/path.py +0 -0
  191. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/update.py +0 -0
  192. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/zh_CN.qm +0 -0
  193. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/zh_CN.ts +0 -0
  194. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/zh_TW.qm +0 -0
  195. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/i18n/zh_TW.ts +0 -0
  196. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/buttons.py +0 -0
  197. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/cards.py +0 -0
  198. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/dialogs.py +0 -0
  199. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/gallery.py +0 -0
  200. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/inputs.py +0 -0
  201. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/labels.py +0 -0
  202. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/layout.py +0 -0
  203. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/navigation.py +0 -0
  204. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/options.py +0 -0
  205. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/popover.py +0 -0
  206. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/qss.py +0 -0
  207. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/switch.py +0 -0
  208. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/theme.py +0 -0
  209. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/kit/window.py +0 -0
  210. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/overlay/OverlayWindow.py +0 -0
  211. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/overlay/__init__.py +0 -0
  212. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/plugins/PluginTab.py +0 -0
  213. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/plugins/__init__.py +0 -0
  214. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/qt.qrc +0 -0
  215. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/resources.py +0 -0
  216. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/settings/GlobalConfigTab.py +0 -0
  217. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/settings/__init__.py +0 -0
  218. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/settings/config_section.py +0 -0
  219. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/settings/settings_page.py +0 -0
  220. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/shell/__init__.py +0 -0
  221. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/shell/connection.py +0 -0
  222. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/shell/diagnostics.py +0 -0
  223. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/shell/lazy_page.py +0 -0
  224. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/shell/log_page.py +0 -0
  225. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/start/__init__.py +0 -0
  226. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/EditTaskTab.py +0 -0
  227. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/MarkUpWindow.py +0 -0
  228. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/ModifyListDialog.py +0 -0
  229. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/PythonHighlighter.py +0 -0
  230. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/RecordScript.py +0 -0
  231. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/ScheduleTaskTab.py +0 -0
  232. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/ScriptPackager.py +0 -0
  233. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/TaskManger.py +0 -0
  234. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/TaskOpButton.py +0 -0
  235. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/TemplateFactory.py +0 -0
  236. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/TemplateTab.py +0 -0
  237. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/__init__.py +0 -0
  238. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/config_editors.py +0 -0
  239. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/config_form.py +0 -0
  240. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/mouse_buttons.py +0 -0
  241. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/tasks/schedule_index_sync.py +0 -0
  242. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/util/Alert.py +0 -0
  243. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/util/InitWorker.py +0 -0
  244. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/util/__init__.py +0 -0
  245. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/util/app.py +0 -0
  246. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/util/download.py +0 -0
  247. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/util/pip_util.py +0 -0
  248. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/util/pyappify_startup.py +0 -0
  249. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/util/touch_scroll.py +0 -0
  250. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/util/windows_thumbnail.py +0 -0
  251. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/Card.py +0 -0
  252. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/CustomTab.py +0 -0
  253. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/FlowLayout.py +0 -0
  254. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/ImageWidget.py +0 -0
  255. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/ImportWarningDialog.py +0 -0
  256. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/ListTableWidgetItem.py +0 -0
  257. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/NumericTableWidgetItem.py +0 -0
  258. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/SortingTableWidgetItem.py +0 -0
  259. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/StartLoadingDialog.py +0 -0
  260. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/Tab.py +0 -0
  261. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/TabWidget.py +0 -0
  262. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/UpdateConfigWidgetItem.py +0 -0
  263. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/YesNonWidgetItem.py +0 -0
  264. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/ui/qt/widget/__init__.py +0 -0
  265. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/update/__init__.py +0 -0
  266. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/update/copy_ok_folder.py +0 -0
  267. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/update/inline_ok_requirements.py +0 -0
  268. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/Analytics.py +0 -0
  269. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/GlobalConfig.py +0 -0
  270. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/__init__.py +0 -0
  271. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/blur.py +0 -0
  272. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/clazz.py +0 -0
  273. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/collection.py +0 -0
  274. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/color.py +0 -0
  275. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/config.py +0 -0
  276. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/explorer.py +0 -0
  277. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/file.py +0 -0
  278. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/gpu_driver_settings.py +0 -0
  279. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/handler.py +0 -0
  280. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/i18n.py +0 -0
  281. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/logger.py +0 -0
  282. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/partial_sync_repo.py +0 -0
  283. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/print_hwnd.py +0 -0
  284. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/process.py +0 -0
  285. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/version.py +0 -0
  286. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/window.py +0 -0
  287. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok/util/windows_schedule.py +0 -0
  288. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok_script.egg-info/SOURCES.txt +0 -0
  289. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok_script.egg-info/dependency_links.txt +0 -0
  290. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok_script.egg-info/entry_points.txt +0 -0
  291. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok_script.egg-info/not-zip-safe +0 -0
  292. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok_script.egg-info/requires.txt +0 -0
  293. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/ok_script.egg-info/top_level.txt +0 -0
  294. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/pyproject.toml +0 -0
  295. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/setup.cfg +0 -0
  296. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/setup.py +0 -0
  297. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_app.py +0 -0
  298. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_base_interaction.py +0 -0
  299. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_blur.py +0 -0
  300. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_box.py +0 -0
  301. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_capture_update.py +0 -0
  302. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_cli.py +0 -0
  303. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_core_events.py +0 -0
  304. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_core_ui_services.py +0 -0
  305. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_device_manager.py +0 -0
  306. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_diagnosis_page.py +0 -0
  307. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_executor_jobs.py +0 -0
  308. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_explorer.py +0 -0
  309. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_global_config.py +0 -0
  310. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_gpu_driver_settings.py +0 -0
  311. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_handler.py +0 -0
  312. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_headless_imports.py +0 -0
  313. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_inline_ok_requirements.py +0 -0
  314. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_lazy_page.py +0 -0
  315. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_log_page.py +0 -0
  316. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_logger.py +0 -0
  317. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_main_window_notifications.py +0 -0
  318. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_main_window_startup_tab.py +0 -0
  319. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_main_window_system_theme.py +0 -0
  320. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_markup_window.py +0 -0
  321. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_mcp_cleanup.py +0 -0
  322. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_mcp_runner.py +0 -0
  323. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_mcp_server.py +0 -0
  324. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_mcp_setting.py +0 -0
  325. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_missing_frame.py +0 -0
  326. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_mouse_buttons.py +0 -0
  327. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_navigation_state.py +0 -0
  328. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_nemu_ipc_capture.py +0 -0
  329. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_notifications.py +0 -0
  330. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_ok_mutex.py +0 -0
  331. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_overlay_custom_draw.py +0 -0
  332. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_overlay_lifecycle.py +0 -0
  333. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_package_metadata.py +0 -0
  334. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_plugin_staging.py +0 -0
  335. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_plugin_tabs.py +0 -0
  336. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_plugins.py +0 -0
  337. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_process.py +0 -0
  338. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_process_mutex.py +0 -0
  339. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_pyappify_startup_update.py +0 -0
  340. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_qt_events.py +0 -0
  341. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_qt_page_layout.py +0 -0
  342. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_runtime_startup.py +0 -0
  343. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_schedule_startup.py +0 -0
  344. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_schedule_task_index_sync.py +0 -0
  345. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_screenshot_naming.py +0 -0
  346. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_screenshot_rendering.py +0 -0
  347. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_settings_page.py +0 -0
  348. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_skills.py +0 -0
  349. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_start_controller.py +0 -0
  350. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_task_executor_next_frame.py +0 -0
  351. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_task_executor_queue.py +0 -0
  352. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_task_reloading.py +0 -0
  353. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_template_compression.py +0 -0
  354. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_template_generation.py +0 -0
  355. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_template_tab.py +0 -0
  356. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_touch_scroll.py +0 -0
  357. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_translation_fallback.py +0 -0
  358. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_ui_config.py +0 -0
  359. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_version.py +0 -0
  360. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_windows_graphics_capture.py +0 -0
  361. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_windows_graphics_hdr.py +0 -0
  362. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_windows_schedule_target_parse.py +0 -0
  363. {ok_script-3.0.0b2 → ok_script-3.0.0b3}/tests/test_windows_schedule_xml.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: ok-script
3
- Version: 3.0.0b2
3
+ Version: 3.0.0b3
4
4
  Summary: Vibe Coding Automation Framework
5
5
  Author-email: ok-oldking <firedcto@gmail.com>
6
6
  License: ok-script License
@@ -31,7 +31,7 @@ from ok.util.config import Config
31
31
 
32
32
  from ok.ui.qt.Communicate import communicate
33
33
  from ok.ui.qt.common.config import cfg as ui_config
34
- from ok.ui.qt.kit import Dialog, KitWindow, NavigationView, Theme as KitTheme, set_toast_bottom_margin, show_toast, \
34
+ from ok.ui.qt.kit import Dialog, KitWindow, NavigationView, Theme as KitTheme, set_toast_anchor, show_toast, \
35
35
  theme as kit_theme
36
36
  from ok.ui.qt.kit.theme import set_style_property
37
37
  from ok.ui.qt.shell.lazy_page import LazyPage
@@ -47,8 +47,6 @@ from ok.util.logger import Logger
47
47
 
48
48
  logger = Logger.get_logger(__name__)
49
49
 
50
- PAGE_MARGIN = 12
51
-
52
50
  SECTION_RUN = "run"
53
51
  SECTION_GAME = "game"
54
52
  SECTION_DEVELOP = "develop"
@@ -115,7 +113,8 @@ class MainWindow(KitWindow):
115
113
  body.setSpacing(0)
116
114
  body.addWidget(self.run_bar)
117
115
  body.addLayout(pages, 1)
118
- set_toast_bottom_margin(self, PAGE_MARGIN)
116
+ # Keep tips flush with the bottom edge of the title bar.
117
+ set_toast_anchor(self, self.title_bar, gap=0)
119
118
 
120
119
  self.schedule_tab = None
121
120
  self.global_config_tabs = [] # [(config, LazyPage)]
@@ -8,7 +8,7 @@ its children; plain Qt inputs inside it are styled too.
8
8
  from ok.ui.qt.kit.buttons import Button
9
9
  from ok.ui.qt.kit.cards import Card, SettingGroup, SettingRow
10
10
  from ok.ui.qt.kit.dialogs import Dialog, confirm
11
- from ok.ui.qt.kit.feedback import Pill, ProgressRing, StatusDot, Toast, set_toast_bottom_margin, show_toast
11
+ from ok.ui.qt.kit.feedback import Pill, ProgressRing, StatusDot, Toast, set_toast_anchor, set_toast_top_margin, show_toast
12
12
  from ok.ui.qt.kit.icons import ICON_NAMES, icon, load_icon
13
13
  from ok.ui.qt.kit.inputs import ComboBox, NumberBox
14
14
  from ok.ui.qt.kit.labels import Label
@@ -25,5 +25,5 @@ __all__ = [
25
25
  "Button", "Card", "ComboBox", "Dialog", "FlowLayout", "ICON_NAMES", "KitWindow", "Label", "NavItem",
26
26
  "NavigationView", "NumberBox", "OptionCard", "OptionGroup", "Pill", "Popover", "ProgressRing", "SettingGroup",
27
27
  "SettingRow", "StatusDot", "Switch", "TabItem", "TabStrip", "Theme", "TitleBar", "Toast", "confirm", "icon",
28
- "load_icon", "set_toast_bottom_margin", "show_toast", "theme",
28
+ "load_icon", "set_toast_anchor", "set_toast_top_margin", "show_toast", "theme",
29
29
  ]
@@ -125,13 +125,15 @@ class ProgressRing(QWidget):
125
125
 
126
126
 
127
127
  class Toast(QWidget):
128
- """A message card shown at the bottom right of a window; see :func:`show_toast`."""
128
+ """A message card shown at the top center of a window; see :func:`show_toast`."""
129
+
130
+ WIDTH = 560
129
131
 
130
132
  def __init__(self, message: str, title: str = None, tone: str = "neutral", action: tuple = None, parent=None):
131
133
  super().__init__(parent)
132
134
  self.setAttribute(Qt.WidgetAttribute.WA_StyledBackground, True)
133
135
  self.tone = _check_tone(tone)
134
- self.setFixedWidth(360)
136
+ self.setFixedWidth(self.WIDTH)
135
137
 
136
138
  icon_label = QLabel(self)
137
139
  icon_label.setPixmap(kit_icon(_TONE_ICON[tone], _TONE_COLOR[tone], 2).pixmap(QSize(18, 18), self.devicePixelRatioF()))
@@ -165,15 +167,19 @@ class Toast(QWidget):
165
167
 
166
168
 
167
169
  class _ToastHost(QObject):
168
- """Stacks toasts in a window's bottom-right corner above ``bottom_margin``."""
170
+ """Stacks toasts down from a window's top center, below ``anchor`` if set."""
169
171
 
170
172
  SPACING = 8
173
+ MARGIN = 16
174
+ ANCHOR_GAP = 4
171
175
 
172
176
  def __init__(self, window: QWidget):
173
177
  super().__init__(window)
174
178
  self.window = window
175
179
  self.toasts = []
176
- self.bottom_margin = 16
180
+ self.anchor = None
181
+ self.anchor_gap = self.ANCHOR_GAP
182
+ self.top_margin = self.MARGIN
177
183
  window.installEventFilter(self)
178
184
 
179
185
  def add(self, toast: Toast, duration: int) -> None:
@@ -182,8 +188,7 @@ class _ToastHost(QObject):
182
188
  toast.destroyed.connect(lambda *_: self._forget(toast))
183
189
  toast.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose, True)
184
190
  self.toasts.append(toast)
185
- # Wrapped labels need height-for-width; adjustSize() would leave gaps.
186
- toast.resize(toast.width(), toast.layout().totalHeightForWidth(toast.width()))
191
+ self._fit(toast)
187
192
  toast.show()
188
193
  toast.raise_()
189
194
  self.layout()
@@ -198,16 +203,30 @@ class _ToastHost(QObject):
198
203
  self.toasts.remove(toast)
199
204
  self.layout()
200
205
 
206
+ def _fit(self, toast) -> None:
207
+ # Narrow windows shrink the toast; wrapped labels need height-for-width,
208
+ # since adjustSize() would leave gaps.
209
+ width = max(240, min(Toast.WIDTH, self.window.width() - 2 * self.MARGIN))
210
+ toast.setFixedWidth(width)
211
+ toast.resize(width, toast.layout().totalHeightForWidth(width))
212
+
213
+ def _top(self) -> int:
214
+ anchor = self.anchor
215
+ if anchor is not None and shiboken6.isValid(anchor) and anchor.isVisible():
216
+ return anchor.mapTo(self.window, anchor.rect().bottomLeft()).y() + 1 + self.anchor_gap
217
+ return self.top_margin
218
+
201
219
  def layout(self) -> None:
202
220
  self.toasts = [toast for toast in self.toasts if toast.isVisible()]
203
- y = self.window.height() - self.bottom_margin
204
- for toast in reversed(self.toasts):
205
- y -= toast.height()
206
- toast.move(self.window.width() - toast.width() - 16, y)
207
- y -= self.SPACING
221
+ y = self._top()
222
+ for toast in self.toasts:
223
+ toast.move((self.window.width() - toast.width()) // 2, y)
224
+ y += toast.height() + self.SPACING
208
225
 
209
226
  def eventFilter(self, watched, event) -> bool:
210
227
  if watched is self.window and event.type() == QEvent.Type.Resize:
228
+ for toast in self.toasts:
229
+ self._fit(toast)
211
230
  self.layout()
212
231
  return False
213
232
 
@@ -231,9 +250,19 @@ def show_toast(parent: QWidget, message: str, title: str = None, tone: str = "ne
231
250
  return toast
232
251
 
233
252
 
234
- def set_toast_bottom_margin(widget: QWidget, margin: int) -> None:
235
- """Keep toasts in ``widget``'s window above e.g. a status bar."""
253
+ def set_toast_anchor(widget: QWidget, anchor: QWidget, *, gap: int = 4) -> None:
254
+ """Show toasts below ``anchor`` with the requested gap in logical pixels."""
255
+
256
+ host = toast_host(widget)
257
+ host.anchor = anchor
258
+ host.anchor_gap = max(0, int(gap))
259
+ host.layout()
260
+
261
+
262
+ def set_toast_top_margin(widget: QWidget, margin: int) -> None:
263
+ """Position toasts directly below the window's top edge."""
236
264
 
237
265
  host = toast_host(widget)
238
- host.bottom_margin = margin
266
+ host.anchor = None
267
+ host.top_margin = max(0, int(margin))
239
268
  host.layout()
@@ -220,6 +220,100 @@ class _SvgFileIconEngine(QIconEngine):
220
220
  return _SvgFileIconEngine(self.data)
221
221
 
222
222
 
223
+ class _RasterFileIconEngine(QIconEngine):
224
+ """Fit raster artwork by its visible bounds, preserving its aspect ratio."""
225
+
226
+ def __init__(self, image: QImage):
227
+ super().__init__()
228
+ self.image = image
229
+
230
+ def paint(self, painter, rect, mode, state):
231
+ scale = min(rect.width() / self.image.width(), rect.height() / self.image.height())
232
+ width, height = self.image.width() * scale, self.image.height() * scale
233
+ target = QRectF(rect.x() + (rect.width() - width) / 2,
234
+ rect.y() + (rect.height() - height) / 2, width, height)
235
+ painter.save()
236
+ painter.setRenderHint(QPainter.RenderHint.SmoothPixmapTransform)
237
+ if mode == QIcon.Mode.Disabled:
238
+ painter.setOpacity(painter.opacity() * 0.4)
239
+ painter.drawImage(target, self.image)
240
+ painter.restore()
241
+
242
+ def pixmap(self, size, mode, state):
243
+ return self.scaledPixmap(size, mode, state, 1.0)
244
+
245
+ def scaledPixmap(self, size, mode, state, scale):
246
+ image = QImage(round(size.width() * scale), round(size.height() * scale),
247
+ QImage.Format.Format_ARGB32_Premultiplied)
248
+ image.fill(Qt.GlobalColor.transparent)
249
+ painter = QPainter(image)
250
+ self.paint(painter, image.rect(), mode, state)
251
+ painter.end()
252
+ result = QPixmap.fromImage(image)
253
+ result.setDevicePixelRatio(scale)
254
+ return result
255
+
256
+ def clone(self):
257
+ return _RasterFileIconEngine(self.image)
258
+
259
+
260
+ class _ColorizedIconEngine(QIconEngine):
261
+ """Tint an icon's alpha mask using a color resolved for the current theme."""
262
+
263
+ def __init__(self, source: QIcon, color):
264
+ super().__init__()
265
+ self.source = source
266
+ self.color = color
267
+
268
+ def paint(self, painter, rect, mode, state):
269
+ size = QSize(max(1, round(rect.width())), max(1, round(rect.height())))
270
+ pixmap = self.scaledPixmap(size, mode, state, painter.device().devicePixelRatioF())
271
+ painter.drawPixmap(rect, pixmap)
272
+
273
+ def pixmap(self, size, mode, state):
274
+ return self.scaledPixmap(size, mode, state, 1.0)
275
+
276
+ def scaledPixmap(self, size, mode, state, scale):
277
+ from ok.ui.qt.kit.theme import theme
278
+
279
+ value = self.color
280
+ if isinstance(value, dict):
281
+ value = value.get("dark" if theme.is_dark() else "light", "text")
282
+ color = theme.color(value) if isinstance(value, str) and not value.startswith("#") else QColor(value)
283
+ if mode == QIcon.Mode.Disabled:
284
+ color.setAlphaF(color.alphaF() * 0.4)
285
+ image = self.source.pixmap(size, scale, QIcon.Mode.Normal, state).toImage()
286
+ painter = QPainter(image)
287
+ painter.setCompositionMode(QPainter.CompositionMode.CompositionMode_SourceIn)
288
+ painter.fillRect(image.rect(), color)
289
+ painter.end()
290
+ result = QPixmap.fromImage(image)
291
+ result.setDevicePixelRatio(image.devicePixelRatio())
292
+ return result
293
+
294
+ def clone(self):
295
+ return _ColorizedIconEngine(self.source, self.color)
296
+
297
+
298
+ def tinted_icon(source: QIcon, color) -> QIcon:
299
+ """Recolor artwork at paint time; ``color`` can supply light/dark shades."""
300
+
301
+ return QIcon(_ColorizedIconEngine(source, color))
302
+
303
+
304
+ def _trim_transparent(image: QImage) -> QImage:
305
+ rgba = image.convertToFormat(QImage.Format.Format_RGBA8888)
306
+ # Ignore nearly invisible export fringes when measuring the artwork.
307
+ occupied = [i for i, alpha in enumerate(bytes(rgba.constBits())[3::4]) if alpha >= 16]
308
+ if not occupied:
309
+ return image
310
+ width = rgba.width()
311
+ left = min(i % width for i in occupied)
312
+ right = max(i % width for i in occupied)
313
+ top, bottom = occupied[0] // width, occupied[-1] // width
314
+ return image.copy(left, top, right - left + 1, bottom - top + 1)
315
+
316
+
223
317
  def icon(name: str, color=None, stroke_width: float = 1.75) -> QIcon:
224
318
  """A bundled icon.
225
319
 
@@ -231,25 +325,32 @@ def icon(name: str, color=None, stroke_width: float = 1.75) -> QIcon:
231
325
 
232
326
 
233
327
  @lru_cache(maxsize=256)
234
- def _load_file_icon(path: str, mtime: float) -> QIcon:
328
+ def _load_file_icon(path: str, mtime: float, trim_transparent: bool = False) -> QIcon:
235
329
  if path.lower().endswith(".svg"):
236
330
  data = Path(path).read_bytes()
237
331
  engine = _SvgFileIconEngine(data)
238
332
  if not engine.renderer.isValid():
239
333
  raise ValueError(f"invalid SVG icon: {path}")
240
334
  return QIcon(engine)
335
+ if trim_transparent:
336
+ image = QImage(path)
337
+ if image.isNull():
338
+ raise ValueError(f"unsupported icon file: {path}")
339
+ return QIcon(_RasterFileIconEngine(_trim_transparent(image)))
241
340
  result = QIcon(path)
242
341
  if result.isNull():
243
342
  raise ValueError(f"unsupported icon file: {path}")
244
343
  return result
245
344
 
246
345
 
247
- def load_icon(source, base_dir=None) -> QIcon:
346
+ def load_icon(source, base_dir=None, *, trim_transparent: bool = False) -> QIcon:
248
347
  """Load an app-provided icon.
249
348
 
250
349
  ``source`` is a path to an ``.svg`` or raster file (relative paths are
251
350
  resolved against ``base_dir`` or the working directory), a ``QIcon``, or
252
351
  ``None`` for no icon.
352
+ ``trim_transparent`` fits raster artwork by its alpha bounds at paint time;
353
+ the source file stays unchanged.
253
354
  """
254
355
 
255
356
  if source is None:
@@ -262,4 +363,4 @@ def load_icon(source, base_dir=None) -> QIcon:
262
363
  path = path.resolve()
263
364
  if not path.is_file():
264
365
  raise FileNotFoundError(f"icon file not found: {path}")
265
- return _load_file_icon(str(path), path.stat().st_mtime)
366
+ return _load_file_icon(str(path), path.stat().st_mtime, trim_transparent)
@@ -54,8 +54,9 @@ class TabItem(QPushButton):
54
54
  self.icon_label.hide()
55
55
  return
56
56
  icon = source if isinstance(source, QIcon) else kit_icon(source, "text" if self.isChecked() else "text_secondary")
57
- self.icon_label.setPixmap(icon.pixmap(QSize(16, 16), self.devicePixelRatioF()))
58
- self.icon_label.setFixedSize(16, 16)
57
+ size = 20 if isinstance(source, QIcon) else 16
58
+ self.icon_label.setPixmap(icon.pixmap(QSize(size, size), self.devicePixelRatioF()))
59
+ self.icon_label.setFixedSize(size, size)
59
60
  self.icon_label.show()
60
61
 
61
62
  def _on_toggled(self, checked: bool) -> None:
@@ -18,6 +18,7 @@ class ImportedTaskTab(TasksPage):
18
18
  def __init__(self, namespace, name):
19
19
  self.namespace = namespace
20
20
  self.imported_file_name = namespace
21
+ self.state_name = f"tasks_page_{namespace}"
21
22
  super().__init__(title=og.app.tr(name))
22
23
 
23
24
  def collect_tasks(self):
@@ -19,7 +19,7 @@ _SEMANTIC = {
19
19
  FALLBACK = "grid"
20
20
 
21
21
 
22
- def nav_icon(source, base_dir=None):
22
+ def nav_icon(source, base_dir=None, *, trim_transparent: bool = False):
23
23
  """A bundled icon name or a QIcon for ``source``.
24
24
 
25
25
  Accepts ``None``, a bundled icon name, an ``ok.core.icons.Icon``, a path to
@@ -43,7 +43,7 @@ def nav_icon(source, base_dir=None):
43
43
  return _SEMANTIC[semantic]
44
44
  if Path(source).suffix.lower() in (".svg", ".png", ".jpg", ".jpeg", ".ico", ".bmp", ".webp"):
45
45
  try:
46
- return load_icon(source, base_dir)
46
+ return load_icon(source, base_dir, trim_transparent=trim_transparent)
47
47
  except (OSError, ValueError):
48
48
  return FALLBACK
49
49
  return FALLBACK
@@ -95,11 +95,10 @@ def compute_run_state(executor, device_manager, starting: bool = False, game_nam
95
95
  return RunState("pause", pause_app, _t("StartCard", "Paused: PC Game Window Must Be in Front!"), "danger")
96
96
  queued = len([t for t in executor.onetime_task_queue if t is not task and t.enabled])
97
97
  return RunState("pause", pause_app, task=task, queued=queued)
98
- if count := executor.active_trigger_task_count():
98
+ if executor.active_trigger_task_count():
99
99
  if not executor.can_capture():
100
100
  return RunState("pause", pause_app, _t("StartCard", "Paused: PC Game Window Must Be in Front!"), "danger")
101
- return RunState("pause", pause_app,
102
- f'{_t("StartCard", "Running")}: {count} {_t("StartCard", "Trigger Tasks")}')
101
+ return RunState("pause", pause_app)
103
102
  return RunState("pause", pause_app, _t("StartCard", "Waiting for task to be enabled"))
104
103
 
105
104
 
@@ -268,7 +267,10 @@ class RunBar(QFrame):
268
267
  button = self.executor_button
269
268
  button.setEnabled(state.button != "disabled")
270
269
  button.setText(state.button_text)
271
- if state.button == "start" or state.button == "disabled":
270
+ if state.button == "start":
271
+ button.set_icon("power")
272
+ button.set_variant("primary")
273
+ elif state.button == "disabled":
272
274
  button.set_icon("power")
273
275
  button.set_variant("tonal")
274
276
  elif state.button == "pause":