frontengine 1.0.0__tar.gz → 1.0.2__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 (158) hide show
  1. {frontengine-1.0.0 → frontengine-1.0.2}/LICENSE +21 -21
  2. frontengine-1.0.2/PKG-INFO +121 -0
  3. frontengine-1.0.2/README.md +97 -0
  4. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/__init__.py +32 -30
  5. frontengine-1.0.2/frontengine/__main__.py +8 -0
  6. frontengine-1.0.2/frontengine/show/base_widget.py +47 -0
  7. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/gif/paint_gif.py +47 -47
  8. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/image/paint_image.py +51 -35
  9. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/load/load_someone_make_ui.py +68 -68
  10. frontengine-1.0.2/frontengine/show/overlay_factory.py +112 -0
  11. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/particle/particle_ui.py +166 -175
  12. frontengine-1.0.2/frontengine/show/pet/desktop_pet.py +178 -0
  13. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/scene/extend_graphic_scene.py +32 -32
  14. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/scene/extend_graphic_view.py +78 -78
  15. frontengine-1.0.2/frontengine/show/scene/scene.py +47 -0
  16. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/sound_player/sound_effect.py +58 -82
  17. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/sound_player/sound_player.py +65 -88
  18. frontengine-1.0.2/frontengine/show/text/draw_text.py +112 -0
  19. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/video/video_player.py +75 -130
  20. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/web/webview.py +87 -108
  21. frontengine-1.0.2/frontengine/show/window_helpers.py +40 -0
  22. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/system_tray/extend_system_tray.py +117 -76
  23. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/ui/color/global_color.py +4 -4
  24. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/ui/dialog/choose_file_dialog.py +105 -95
  25. frontengine-1.0.2/frontengine/ui/dialog/hotkey_settings_dialog.py +112 -0
  26. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/ui/dialog/save_file_dialog.py +26 -26
  27. frontengine-1.0.2/frontengine/ui/main_ui.py +408 -0
  28. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/ui/menu/help_menu.py +61 -61
  29. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/ui/menu/how_to_menu.py +44 -44
  30. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/ui/menu/language_menu.py +57 -57
  31. frontengine-1.0.2/frontengine/ui/menu/preset_menu.py +299 -0
  32. frontengine-1.0.2/frontengine/ui/menu/settings_menu.py +111 -0
  33. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/ui/page/control_center/control_center_ui.py +273 -158
  34. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/ui/page/gif/gif_setting_ui.py +207 -132
  35. frontengine-1.0.2/frontengine/ui/page/image/image_setting_ui.py +286 -0
  36. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/ui/page/particle/particle_setting_ui.py +240 -170
  37. frontengine-1.0.2/frontengine/ui/page/pet/pet_setting_ui.py +154 -0
  38. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/ui/page/scene_setting/scene_manager.py +120 -120
  39. frontengine-1.0.2/frontengine/ui/page/scene_setting/scene_page/base_scene_page.py +72 -0
  40. frontengine-1.0.2/frontengine/ui/page/scene_setting/scene_page/gif.py +52 -0
  41. frontengine-1.0.2/frontengine/ui/page/scene_setting/scene_page/image.py +47 -0
  42. frontengine-1.0.2/frontengine/ui/page/scene_setting/scene_page/registry.py +18 -0
  43. frontengine-1.0.2/frontengine/ui/page/scene_setting/scene_page/sound.py +49 -0
  44. frontengine-1.0.2/frontengine/ui/page/scene_setting/scene_page/text.py +45 -0
  45. frontengine-1.0.2/frontengine/ui/page/scene_setting/scene_page/video.py +57 -0
  46. frontengine-1.0.2/frontengine/ui/page/scene_setting/scene_page/web.py +35 -0
  47. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/ui/page/scene_setting/scene_setting_ui.py +42 -56
  48. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/ui/page/sound_player/sound_player_setting_ui.py +131 -111
  49. frontengine-1.0.2/frontengine/ui/page/text/text_setting_ui.py +235 -0
  50. frontengine-1.0.2/frontengine/ui/page/utils.py +272 -0
  51. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/ui/page/video/video_setting_ui.py +236 -156
  52. frontengine-1.0.2/frontengine/ui/page/web/web_setting_ui.py +189 -0
  53. frontengine-1.0.2/frontengine/user_setting/preset_repository.py +209 -0
  54. frontengine-1.0.2/frontengine/user_setting/scene_setting.py +46 -0
  55. frontengine-1.0.2/frontengine/user_setting/user_setting_file.py +131 -0
  56. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/browser/browser.py +20 -20
  57. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/critical_exit/check_key_is_press.py +19 -19
  58. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/critical_exit/critical_exit.py +64 -64
  59. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/critical_exit/win32_vk.py +368 -368
  60. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/exception/__init__.py +1 -1
  61. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/exception/exception_tags.py +10 -10
  62. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/exception/exceptions.py +18 -18
  63. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/file/open/__init__.py +1 -1
  64. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/file/open/open_file.py +35 -35
  65. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/file/save/__init__.py +1 -1
  66. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/file/save/save_file.py +32 -32
  67. frontengine-1.0.2/frontengine/utils/hotkey/hotkey_service.py +99 -0
  68. frontengine-1.0.2/frontengine/utils/json/json_file.py +37 -0
  69. frontengine-1.0.2/frontengine/utils/json/json_repository.py +42 -0
  70. frontengine-1.0.2/frontengine/utils/json_format/__init__.py +1 -0
  71. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/json_format/json_process.py +41 -41
  72. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/logging/loggin_instance.py +45 -45
  73. frontengine-1.0.2/frontengine/utils/multi_language/__init__.py +0 -0
  74. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/multi_language/english.py +225 -146
  75. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/multi_language/france.py +147 -147
  76. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/multi_language/germany.py +147 -147
  77. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/multi_language/italy.py +147 -147
  78. frontengine-1.0.2/frontengine/utils/multi_language/language_wrapper.py +52 -0
  79. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/multi_language/russian.py +147 -147
  80. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/multi_language/simplified_chinese.py +147 -147
  81. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/multi_language/traditional_chinese.py +226 -147
  82. frontengine-1.0.2/frontengine/utils/preset_schedule/__init__.py +0 -0
  83. frontengine-1.0.2/frontengine/utils/preset_schedule/preset_schedule_service.py +85 -0
  84. frontengine-1.0.2/frontengine/utils/redirect_manager/__init__.py +0 -0
  85. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/utils/redirect_manager/redirect_manager_class.py +84 -84
  86. frontengine-1.0.2/frontengine/utils/smart_pause/__init__.py +0 -0
  87. frontengine-1.0.2/frontengine/utils/smart_pause/smart_pause_service.py +119 -0
  88. frontengine-1.0.2/frontengine/utils/theme_schedule/__init__.py +0 -0
  89. frontengine-1.0.2/frontengine/utils/theme_schedule/theme_schedule_service.py +97 -0
  90. frontengine-1.0.2/frontengine/utils/web_url.py +49 -0
  91. frontengine-1.0.2/frontengine/worker/__init__.py +0 -0
  92. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/worker/qthread_worker.py +59 -59
  93. frontengine-1.0.2/frontengine.egg-info/PKG-INFO +121 -0
  94. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine.egg-info/SOURCES.txt +24 -0
  95. frontengine-1.0.2/frontengine.egg-info/entry_points.txt +2 -0
  96. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine.egg-info/requires.txt +1 -0
  97. {frontengine-1.0.0 → frontengine-1.0.2}/pyproject.toml +40 -37
  98. {frontengine-1.0.0 → frontengine-1.0.2}/setup.cfg +4 -4
  99. frontengine-1.0.0/PKG-INFO +0 -73
  100. frontengine-1.0.0/README.md +0 -50
  101. frontengine-1.0.0/frontengine/show/base_widget.py +0 -83
  102. frontengine-1.0.0/frontengine/show/scene/scene.py +0 -120
  103. frontengine-1.0.0/frontengine/show/text/draw_text.py +0 -131
  104. frontengine-1.0.0/frontengine/ui/main_ui.py +0 -221
  105. frontengine-1.0.0/frontengine/ui/page/image/image_setting_ui.py +0 -116
  106. frontengine-1.0.0/frontengine/ui/page/scene_setting/scene_page/gif.py +0 -87
  107. frontengine-1.0.0/frontengine/ui/page/scene_setting/scene_page/image.py +0 -72
  108. frontengine-1.0.0/frontengine/ui/page/scene_setting/scene_page/sound.py +0 -77
  109. frontengine-1.0.0/frontengine/ui/page/scene_setting/scene_page/text.py +0 -80
  110. frontengine-1.0.0/frontengine/ui/page/scene_setting/scene_page/video.py +0 -107
  111. frontengine-1.0.0/frontengine/ui/page/scene_setting/scene_page/web.py +0 -58
  112. frontengine-1.0.0/frontengine/ui/page/text/text_setting_ui.py +0 -124
  113. frontengine-1.0.0/frontengine/ui/page/utils.py +0 -84
  114. frontengine-1.0.0/frontengine/ui/page/web/web_setting_ui.py +0 -115
  115. frontengine-1.0.0/frontengine/user_setting/scene_setting.py +0 -70
  116. frontengine-1.0.0/frontengine/user_setting/user_setting_file.py +0 -37
  117. frontengine-1.0.0/frontengine/utils/json/json_file.py +0 -43
  118. frontengine-1.0.0/frontengine/utils/json_format/__init__.py +0 -1
  119. frontengine-1.0.0/frontengine/utils/multi_language/language_wrapper.py +0 -41
  120. frontengine-1.0.0/frontengine.egg-info/PKG-INFO +0 -73
  121. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/__init__.py +0 -0
  122. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/gif/__init__.py +0 -0
  123. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/image/__init__.py +0 -0
  124. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/load/__init__.py +0 -0
  125. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine/show/particle/__init__.py +0 -0
  126. {frontengine-1.0.0/frontengine/show/scene → frontengine-1.0.2/frontengine/show/pet}/__init__.py +0 -0
  127. {frontengine-1.0.0/frontengine/show/sound_player → frontengine-1.0.2/frontengine/show/scene}/__init__.py +0 -0
  128. {frontengine-1.0.0/frontengine/show/text → frontengine-1.0.2/frontengine/show/sound_player}/__init__.py +0 -0
  129. {frontengine-1.0.0/frontengine/show/video → frontengine-1.0.2/frontengine/show/text}/__init__.py +0 -0
  130. {frontengine-1.0.0/frontengine/show/web → frontengine-1.0.2/frontengine/show/video}/__init__.py +0 -0
  131. {frontengine-1.0.0/frontengine/system_tray → frontengine-1.0.2/frontengine/show/web}/__init__.py +0 -0
  132. {frontengine-1.0.0/frontengine/ui → frontengine-1.0.2/frontengine/system_tray}/__init__.py +0 -0
  133. {frontengine-1.0.0/frontengine/ui/color → frontengine-1.0.2/frontengine/ui}/__init__.py +0 -0
  134. {frontengine-1.0.0/frontengine/ui/dialog → frontengine-1.0.2/frontengine/ui/color}/__init__.py +0 -0
  135. {frontengine-1.0.0/frontengine/ui/menu → frontengine-1.0.2/frontengine/ui/dialog}/__init__.py +0 -0
  136. {frontengine-1.0.0/frontengine/ui/page → frontengine-1.0.2/frontengine/ui/menu}/__init__.py +0 -0
  137. {frontengine-1.0.0/frontengine/ui/page/control_center → frontengine-1.0.2/frontengine/ui/page}/__init__.py +0 -0
  138. {frontengine-1.0.0/frontengine/ui/page/gif → frontengine-1.0.2/frontengine/ui/page/control_center}/__init__.py +0 -0
  139. {frontengine-1.0.0/frontengine/ui/page/image → frontengine-1.0.2/frontengine/ui/page/gif}/__init__.py +0 -0
  140. {frontengine-1.0.0/frontengine/ui/page/particle → frontengine-1.0.2/frontengine/ui/page/image}/__init__.py +0 -0
  141. {frontengine-1.0.0/frontengine/ui/page/scene_setting → frontengine-1.0.2/frontengine/ui/page/particle}/__init__.py +0 -0
  142. {frontengine-1.0.0/frontengine/ui/page/scene_setting/scene_page → frontengine-1.0.2/frontengine/ui/page/pet}/__init__.py +0 -0
  143. {frontengine-1.0.0/frontengine/ui/page/sound_player → frontengine-1.0.2/frontengine/ui/page/scene_setting}/__init__.py +0 -0
  144. {frontengine-1.0.0/frontengine/ui/page/text → frontengine-1.0.2/frontengine/ui/page/scene_setting/scene_page}/__init__.py +0 -0
  145. {frontengine-1.0.0/frontengine/ui/page/video → frontengine-1.0.2/frontengine/ui/page/sound_player}/__init__.py +0 -0
  146. {frontengine-1.0.0/frontengine/ui/page/web → frontengine-1.0.2/frontengine/ui/page/text}/__init__.py +0 -0
  147. {frontengine-1.0.0/frontengine/user_setting → frontengine-1.0.2/frontengine/ui/page/video}/__init__.py +0 -0
  148. {frontengine-1.0.0/frontengine/utils → frontengine-1.0.2/frontengine/ui/page/web}/__init__.py +0 -0
  149. {frontengine-1.0.0/frontengine/utils/browser → frontengine-1.0.2/frontengine/user_setting}/__init__.py +0 -0
  150. {frontengine-1.0.0/frontengine/utils/critical_exit → frontengine-1.0.2/frontengine/utils}/__init__.py +0 -0
  151. {frontengine-1.0.0/frontengine/utils/file → frontengine-1.0.2/frontengine/utils/browser}/__init__.py +0 -0
  152. {frontengine-1.0.0/frontengine/utils/json → frontengine-1.0.2/frontengine/utils/critical_exit}/__init__.py +0 -0
  153. {frontengine-1.0.0/frontengine/utils/logging → frontengine-1.0.2/frontengine/utils/file}/__init__.py +0 -0
  154. {frontengine-1.0.0/frontengine/utils/multi_language → frontengine-1.0.2/frontengine/utils/hotkey}/__init__.py +0 -0
  155. {frontengine-1.0.0/frontengine/utils/redirect_manager → frontengine-1.0.2/frontengine/utils/json}/__init__.py +0 -0
  156. {frontengine-1.0.0/frontengine/worker → frontengine-1.0.2/frontengine/utils/logging}/__init__.py +0 -0
  157. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine.egg-info/dependency_links.txt +0 -0
  158. {frontengine-1.0.0 → frontengine-1.0.2}/frontengine.egg-info/top_level.txt +0 -0
@@ -1,21 +1,21 @@
1
- MIT License
2
-
3
- Copyright (c) 2023 JE-Chen
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining a copy
6
- of this software and associated documentation files (the "Software"), to deal
7
- in the Software without restriction, including without limitation the rights
8
- to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
- copies of the Software, and to permit persons to whom the Software is
10
- furnished to do so, subject to the following conditions:
11
-
12
- The above copyright notice and this permission notice shall be included in all
13
- copies or substantial portions of the Software.
14
-
15
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
- IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
- FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
- AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
- LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
- OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
- SOFTWARE.
1
+ MIT License
2
+
3
+ Copyright (c) 2023 JE-Chen
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,121 @@
1
+ Metadata-Version: 2.4
2
+ Name: frontengine
3
+ Version: 1.0.2
4
+ Summary: FrontEngine is use-define frontview or only use like screen saver
5
+ Author-email: JE-Chen <jechenmailman@gmail.com>
6
+ Project-URL: Homepage, https://github.com/Intergration-Automation-Testing/FrontEngine
7
+ Project-URL: Code, https://github.com/Intergration-Automation-Testing/FrontEngine
8
+ Classifier: Programming Language :: Python :: 3.10
9
+ Classifier: Development Status :: 2 - Pre-Alpha
10
+ Classifier: Environment :: Win32 (MS Windows)
11
+ Classifier: Environment :: MacOS X
12
+ Classifier: Environment :: X11 Applications
13
+ Classifier: Operating System :: OS Independent
14
+ Requires-Python: >=3.10
15
+ Description-Content-Type: text/markdown
16
+ License-File: LICENSE
17
+ Requires-Dist: PySide6==6.10.2
18
+ Requires-Dist: qt-material
19
+ Requires-Dist: PyOpenGL
20
+ Requires-Dist: PyOpenGL_accelerate
21
+ Requires-Dist: numpy
22
+ Requires-Dist: pynput
23
+ Dynamic: license-file
24
+
25
+ # FrontEngine
26
+
27
+ [Support this project on Steam](https://store.steampowered.com/app/2793470/FrontEngine/)
28
+
29
+ ## About
30
+
31
+ FrontEngine is a lightweight and flexible framework designed to simplify automation and visualization tasks.
32
+ It provides an intuitive interface and supports multiple media formats for interactive demonstrations.
33
+
34
+ ![FrontEngine UI](image/FrontEngine.png)
35
+
36
+ ---
37
+
38
+ ## Features
39
+
40
+ - **GIFs & Animations**
41
+ *(GIFs may take time to load)*
42
+ ![GIF](gifs/play_gif.gif)
43
+ ![WEBP](gifs/webp.gif)
44
+
45
+ - **Video**
46
+ ![Video](gifs/video.gif)
47
+
48
+ - **Website**
49
+ ![Website](gifs/website.gif)
50
+
51
+ - **YouTube Showcase**
52
+ [Watch on YouTube](https://youtu.be/fewogcb3b8Y)
53
+
54
+ ---
55
+
56
+ ## Install
57
+
58
+ - **System Requirements**
59
+ - Python **3.10+**
60
+ - Windows 10/11 is the primary target; macOS and Linux are supported but may need extra OS dependencies.
61
+
62
+ - **From PyPI**
63
+ ```bash
64
+ pip install frontengine
65
+ ```
66
+
67
+ - **Pre-built binaries**
68
+ - [GitHub Releases](https://github.com/Intergration-Automation-Testing/FrontEngine/releases)
69
+
70
+ ---
71
+
72
+ ## Development
73
+
74
+ - Requires **Python 3.10+**.
75
+ - Install the dev toolchain:
76
+ ```bash
77
+ pip install -r dev_requirements.txt
78
+ pip install -e .
79
+ ```
80
+ - Run the unit smoke tests:
81
+ ```bash
82
+ python ./tests/unit_test/start/start_front_engine.py
83
+ python ./tests/unit_test/start/extend_front_engine.py
84
+ ```
85
+ - Contributions and pull requests are welcome!
86
+
87
+ ---
88
+
89
+ ## Continuous Integration & Release
90
+
91
+ This repository ships two GitHub Actions workflows:
92
+
93
+ | Workflow | Trigger | Purpose |
94
+ |----------|---------|---------|
95
+ | `CI` (`.github/workflows/ci.yml`) | Push / PR to `main` or `dev`, daily cron | Matrix smoke test across Python 3.10 / 3.11 / 3.12 on Windows |
96
+ | `Release` (`.github/workflows/release.yml`) | A pull request is merged into `main` (or manual dispatch) | Auto-bumps the version in `stable.toml`/`pyproject.toml`, commits the bump back to `main`, swaps `stable.toml` → `pyproject.toml`, builds sdist + wheel, uploads to PyPI as `frontengine` via `twine`, creates a GitHub release tagged `v<version>` |
97
+
98
+ Publishing **only happens on merge to `main`** — pushing to `dev` runs CI but
99
+ never publishes. On merge, the workflow **automatically bumps the patch
100
+ segment** of the version (configurable via manual dispatch: `patch` / `minor`
101
+ / `major`), commits the bump back to `main` with `[skip ci]`, then builds,
102
+ uploads, and releases under the new version. Both the PyPI upload and the
103
+ GitHub release see the bumped version, not the previous one.
104
+
105
+ ### Cutting a new release
106
+
107
+ 1. Merge a pull request into `main` — the patch version bumps automatically.
108
+ 2. That's it. PyPI publish and GitHub release happen in one workflow run.
109
+
110
+ For a minor or major bump, trigger the workflow manually via *Actions →
111
+ Release → Run workflow* and pick the `bump` segment. That path also works
112
+ when you need to re-run a failed publish without a new merge.
113
+
114
+ ### Required repository secrets
115
+
116
+ | Secret | Used by | Contents |
117
+ |--------|---------|----------|
118
+ | `PYPI_API_TOKEN` | `release.yml` | A PyPI API token scoped to the `frontengine` project |
119
+
120
+ The workflow uses `__token__` as the twine username, so only the token itself
121
+ needs to be stored.
@@ -0,0 +1,97 @@
1
+ # FrontEngine
2
+
3
+ [Support this project on Steam](https://store.steampowered.com/app/2793470/FrontEngine/)
4
+
5
+ ## About
6
+
7
+ FrontEngine is a lightweight and flexible framework designed to simplify automation and visualization tasks.
8
+ It provides an intuitive interface and supports multiple media formats for interactive demonstrations.
9
+
10
+ ![FrontEngine UI](image/FrontEngine.png)
11
+
12
+ ---
13
+
14
+ ## Features
15
+
16
+ - **GIFs & Animations**
17
+ *(GIFs may take time to load)*
18
+ ![GIF](gifs/play_gif.gif)
19
+ ![WEBP](gifs/webp.gif)
20
+
21
+ - **Video**
22
+ ![Video](gifs/video.gif)
23
+
24
+ - **Website**
25
+ ![Website](gifs/website.gif)
26
+
27
+ - **YouTube Showcase**
28
+ [Watch on YouTube](https://youtu.be/fewogcb3b8Y)
29
+
30
+ ---
31
+
32
+ ## Install
33
+
34
+ - **System Requirements**
35
+ - Python **3.10+**
36
+ - Windows 10/11 is the primary target; macOS and Linux are supported but may need extra OS dependencies.
37
+
38
+ - **From PyPI**
39
+ ```bash
40
+ pip install frontengine
41
+ ```
42
+
43
+ - **Pre-built binaries**
44
+ - [GitHub Releases](https://github.com/Intergration-Automation-Testing/FrontEngine/releases)
45
+
46
+ ---
47
+
48
+ ## Development
49
+
50
+ - Requires **Python 3.10+**.
51
+ - Install the dev toolchain:
52
+ ```bash
53
+ pip install -r dev_requirements.txt
54
+ pip install -e .
55
+ ```
56
+ - Run the unit smoke tests:
57
+ ```bash
58
+ python ./tests/unit_test/start/start_front_engine.py
59
+ python ./tests/unit_test/start/extend_front_engine.py
60
+ ```
61
+ - Contributions and pull requests are welcome!
62
+
63
+ ---
64
+
65
+ ## Continuous Integration & Release
66
+
67
+ This repository ships two GitHub Actions workflows:
68
+
69
+ | Workflow | Trigger | Purpose |
70
+ |----------|---------|---------|
71
+ | `CI` (`.github/workflows/ci.yml`) | Push / PR to `main` or `dev`, daily cron | Matrix smoke test across Python 3.10 / 3.11 / 3.12 on Windows |
72
+ | `Release` (`.github/workflows/release.yml`) | A pull request is merged into `main` (or manual dispatch) | Auto-bumps the version in `stable.toml`/`pyproject.toml`, commits the bump back to `main`, swaps `stable.toml` → `pyproject.toml`, builds sdist + wheel, uploads to PyPI as `frontengine` via `twine`, creates a GitHub release tagged `v<version>` |
73
+
74
+ Publishing **only happens on merge to `main`** — pushing to `dev` runs CI but
75
+ never publishes. On merge, the workflow **automatically bumps the patch
76
+ segment** of the version (configurable via manual dispatch: `patch` / `minor`
77
+ / `major`), commits the bump back to `main` with `[skip ci]`, then builds,
78
+ uploads, and releases under the new version. Both the PyPI upload and the
79
+ GitHub release see the bumped version, not the previous one.
80
+
81
+ ### Cutting a new release
82
+
83
+ 1. Merge a pull request into `main` — the patch version bumps automatically.
84
+ 2. That's it. PyPI publish and GitHub release happen in one workflow run.
85
+
86
+ For a minor or major bump, trigger the workflow manually via *Actions →
87
+ Release → Run workflow* and pick the `bump` segment. That path also works
88
+ when you need to re-run a failed publish without a new merge.
89
+
90
+ ### Required repository secrets
91
+
92
+ | Secret | Used by | Contents |
93
+ |--------|---------|----------|
94
+ | `PYPI_API_TOKEN` | `release.yml` | A PyPI API token scoped to the `frontengine` project |
95
+
96
+ The workflow uses `__token__` as the twine username, so only the token itself
97
+ needs to be stored.
@@ -1,30 +1,32 @@
1
- from frontengine.show.gif.paint_gif import GifWidget
2
- from frontengine.show.image.paint_image import ImageWidget
3
- from frontengine.show.load.load_someone_make_ui import load_extend_ui_file
4
- from frontengine.show.load.load_someone_make_ui import load_ui_file
5
- from frontengine.show.sound_player.sound_effect import SoundEffectWidget
6
- from frontengine.show.sound_player.sound_player import SoundPlayer
7
- from frontengine.show.text.draw_text import TextWidget
8
- from frontengine.show.video.video_player import VideoWidget
9
- from frontengine.show.web.webview import WebWidget
10
- from frontengine.ui.main_ui import start_front_engine
11
- from frontengine.utils.multi_language.language_wrapper import language_wrapper
12
- from frontengine.ui.page.text.text_setting_ui import TextSettingUI
13
- from frontengine.ui.page.web.web_setting_ui import WEBSettingUI
14
- from frontengine.ui.page.gif.gif_setting_ui import GIFSettingUI
15
- from frontengine.ui.page.image.image_setting_ui import ImageSettingUI
16
- from frontengine.ui.page.sound_player.sound_player_setting_ui import SoundPlayerSettingUI
17
- from frontengine.ui.page.video.video_setting_ui import VideoSettingUI
18
- from frontengine.ui.page.control_center.control_center_ui import ControlCenterUI
19
- from frontengine.ui.page.scene_setting.scene_setting_ui import SceneSettingUI
20
- from frontengine.ui.main_ui import FrontEngineMainUI
21
- from frontengine.ui.main_ui import FrontEngine_EXTEND_TAB
22
- from frontengine.utils.redirect_manager.redirect_manager_class import RedirectManager
23
-
24
- __all__ = [
25
- "start_front_engine", "GifWidget", "SoundPlayer", "SoundEffectWidget", "TextWidget",
26
- "WebWidget", "ImageWidget", "VideoWidget", "language_wrapper", "load_extend_ui_file", "load_ui_file",
27
- "TextSettingUI", "WEBSettingUI", "GIFSettingUI", "ImageSettingUI", "SoundPlayerSettingUI",
28
- "VideoSettingUI", "ControlCenterUI", "SceneSettingUI", "FrontEngineMainUI",
29
- "FrontEngine_EXTEND_TAB", "RedirectManager"
30
- ]
1
+ from frontengine.show.gif.paint_gif import GifWidget
2
+ from frontengine.show.image.paint_image import ImageWidget
3
+ from frontengine.show.load.load_someone_make_ui import load_extend_ui_file
4
+ from frontengine.show.load.load_someone_make_ui import load_ui_file
5
+ from frontengine.show.sound_player.sound_effect import SoundEffectWidget
6
+ from frontengine.show.sound_player.sound_player import SoundPlayer
7
+ from frontengine.show.pet.desktop_pet import DesktopPetWidget
8
+ from frontengine.show.text.draw_text import TextWidget
9
+ from frontengine.show.video.video_player import VideoWidget
10
+ from frontengine.show.web.webview import WebWidget
11
+ from frontengine.ui.main_ui import start_front_engine
12
+ from frontengine.utils.multi_language.language_wrapper import language_wrapper
13
+ from frontengine.ui.page.text.text_setting_ui import TextSettingUI
14
+ from frontengine.ui.page.web.web_setting_ui import WEBSettingUI
15
+ from frontengine.ui.page.gif.gif_setting_ui import GIFSettingUI
16
+ from frontengine.ui.page.image.image_setting_ui import ImageSettingUI
17
+ from frontengine.ui.page.sound_player.sound_player_setting_ui import SoundPlayerSettingUI
18
+ from frontengine.ui.page.video.video_setting_ui import VideoSettingUI
19
+ from frontengine.ui.page.control_center.control_center_ui import ControlCenterUI
20
+ from frontengine.ui.page.pet.pet_setting_ui import PetSettingUI
21
+ from frontengine.ui.page.scene_setting.scene_setting_ui import SceneSettingUI
22
+ from frontengine.ui.main_ui import FrontEngineMainUI
23
+ from frontengine.ui.main_ui import FrontEngine_EXTEND_TAB
24
+ from frontengine.utils.redirect_manager.redirect_manager_class import RedirectManager
25
+
26
+ __all__ = [
27
+ "start_front_engine", "GifWidget", "SoundPlayer", "SoundEffectWidget", "TextWidget",
28
+ "WebWidget", "ImageWidget", "VideoWidget", "language_wrapper", "load_extend_ui_file", "load_ui_file",
29
+ "TextSettingUI", "WEBSettingUI", "GIFSettingUI", "ImageSettingUI", "SoundPlayerSettingUI",
30
+ "VideoSettingUI", "ControlCenterUI", "SceneSettingUI", "FrontEngineMainUI",
31
+ "FrontEngine_EXTEND_TAB", "RedirectManager", "DesktopPetWidget", "PetSettingUI"
32
+ ]
@@ -0,0 +1,8 @@
1
+ """
2
+ 允許以 `python -m frontengine [--preset NAME] [--debug]` 啟動。
3
+ Enable `python -m frontengine [--preset NAME] [--debug]`.
4
+ """
5
+ from frontengine.ui.main_ui import main
6
+
7
+ if __name__ == "__main__":
8
+ main()
@@ -0,0 +1,47 @@
1
+ from abc import abstractmethod
2
+
3
+ from PySide6.QtCore import Qt
4
+ from PySide6.QtGui import QPainter
5
+ from PySide6.QtWidgets import QWidget
6
+
7
+ from frontengine.show.window_helpers import apply_overlay_window_flags, load_overlay_icon
8
+ from frontengine.utils.logging.loggin_instance import front_engine_logger
9
+
10
+
11
+ class BaseWidget(QWidget):
12
+ """
13
+ BaseWidget: 提供共用 UI 屬性與事件處理的基底類別
14
+ BaseWidget: Base class providing shared UI attributes and event handling
15
+ """
16
+
17
+ def __init__(self, draw_location_x: int = 0, draw_location_y: int = 0):
18
+ super().__init__()
19
+ self.draw_location_x: int = draw_location_x
20
+ self.draw_location_y: int = draw_location_y
21
+ self.opacity: float = 0.2
22
+
23
+ self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
24
+ self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
25
+ load_overlay_icon(self)
26
+
27
+ def set_ui_window_flag(self, show_on_bottom: bool = False) -> None:
28
+ front_engine_logger.info(f"{self.__class__.__name__} set_ui_window_flag | show_on_bottom: {show_on_bottom}")
29
+ apply_overlay_window_flags(self, show_on_bottom=show_on_bottom)
30
+
31
+ def set_ui_variable(self, opacity: float = 0.2) -> None:
32
+ front_engine_logger.info(f"{self.__class__.__name__} set_ui_variable | opacity: {opacity}")
33
+ self.opacity = opacity
34
+
35
+ def paintEvent(self, event) -> None:
36
+ front_engine_logger.debug(f"{self.__class__.__name__} paintEvent | event: {event}")
37
+ painter = QPainter(self)
38
+ painter.save()
39
+ painter.setOpacity(self.opacity)
40
+ try:
41
+ self.draw_content(painter)
42
+ finally:
43
+ painter.restore()
44
+
45
+ @abstractmethod
46
+ def draw_content(self, painter: QPainter) -> None:
47
+ """Subclass hook that renders the widget content onto the shared painter."""
@@ -1,47 +1,47 @@
1
- from pathlib import Path
2
-
3
- from PySide6.QtCore import QRect
4
- from PySide6.QtGui import QPainter, QMovie
5
- from PySide6.QtWidgets import QMessageBox, QLabel
6
-
7
- from frontengine.show.base_widget import BaseWidget
8
- from frontengine.utils.logging.loggin_instance import front_engine_logger
9
- from frontengine.utils.multi_language.language_wrapper import language_wrapper
10
-
11
-
12
- class GifWidget(BaseWidget):
13
- """
14
- GifWidget: 顯示 GIF 動畫
15
- GifWidget: Display animated GIF
16
- """
17
-
18
- def __init__(self, gif_image_path: str, draw_location_x: int = 0, draw_location_y: int = 0):
19
- super().__init__(draw_location_x, draw_location_y)
20
- self.speed: int = 100
21
- self.gif_path: Path = Path(gif_image_path)
22
- self.movie: QMovie = QMovie()
23
- self.gif_label: QLabel = QLabel()
24
-
25
- if self.gif_path.exists() and self.gif_path.is_file():
26
- front_engine_logger.info(f"Loading GIF file: {self.gif_path}")
27
- self.movie.setFileName(str(self.gif_path))
28
- self.movie.frameChanged.connect(self.repaint)
29
- self.gif_label.setMovie(self.movie)
30
- self.movie.start()
31
- self.resize(self.movie.frameRect().size())
32
- else:
33
- message_box: QMessageBox = QMessageBox(self)
34
- message_box.setText(language_wrapper.language_word_dict.get("paint_gif_message_box_text"))
35
- message_box.show()
36
-
37
- def set_gif_variable(self, speed: int = 100) -> None:
38
- front_engine_logger.info(f"GifWidget set_gif_variable | speed: {speed}")
39
- self.speed = speed
40
- self.movie.setSpeed(self.speed)
41
-
42
- def draw_content(self, painter: QPainter) -> None:
43
- current_gif_frame = self.movie.currentPixmap()
44
- painter.drawPixmap(
45
- QRect(self.draw_location_x, self.draw_location_y, self.width(), self.height()),
46
- current_gif_frame
47
- )
1
+ from pathlib import Path
2
+
3
+ from PySide6.QtCore import QRect
4
+ from PySide6.QtGui import QPainter, QMovie
5
+ from PySide6.QtWidgets import QMessageBox, QLabel
6
+
7
+ from frontengine.show.base_widget import BaseWidget
8
+ from frontengine.utils.logging.loggin_instance import front_engine_logger
9
+ from frontengine.utils.multi_language.language_wrapper import language_wrapper
10
+
11
+
12
+ class GifWidget(BaseWidget):
13
+ """
14
+ GifWidget: 顯示 GIF 動畫
15
+ GifWidget: Display animated GIF
16
+ """
17
+
18
+ def __init__(self, gif_image_path: str, draw_location_x: int = 0, draw_location_y: int = 0):
19
+ super().__init__(draw_location_x, draw_location_y)
20
+ self.speed: int = 100
21
+ self.gif_path: Path = Path(gif_image_path)
22
+ self.movie: QMovie = QMovie()
23
+ self.gif_label: QLabel = QLabel()
24
+
25
+ if self.gif_path.exists() and self.gif_path.is_file():
26
+ front_engine_logger.info(f"Loading GIF file: {self.gif_path}")
27
+ self.movie.setFileName(str(self.gif_path))
28
+ self.movie.frameChanged.connect(self.repaint)
29
+ self.gif_label.setMovie(self.movie)
30
+ self.movie.start()
31
+ self.resize(self.movie.frameRect().size())
32
+ else:
33
+ message_box: QMessageBox = QMessageBox(self)
34
+ message_box.setText(language_wrapper.language_word_dict.get("paint_gif_message_box_text"))
35
+ message_box.show()
36
+
37
+ def set_gif_variable(self, speed: int = 100) -> None:
38
+ front_engine_logger.info(f"GifWidget set_gif_variable | speed: {speed}")
39
+ self.speed = speed
40
+ self.movie.setSpeed(self.speed)
41
+
42
+ def draw_content(self, painter: QPainter) -> None:
43
+ current_gif_frame = self.movie.currentPixmap()
44
+ painter.drawPixmap(
45
+ QRect(self.draw_location_x, self.draw_location_y, self.width(), self.height()),
46
+ current_gif_frame
47
+ )
@@ -1,35 +1,51 @@
1
- from pathlib import Path
2
-
3
- from PySide6.QtCore import QRect
4
- from PySide6.QtGui import QPainter, QImage
5
- from PySide6.QtWidgets import QMessageBox
6
-
7
- from frontengine.show.base_widget import BaseWidget
8
- from frontengine.utils.logging.loggin_instance import front_engine_logger
9
- from frontengine.utils.multi_language.language_wrapper import language_wrapper
10
-
11
-
12
- class ImageWidget(BaseWidget):
13
- """
14
- ImageWidget: 顯示靜態圖片
15
- ImageWidget: Display static image
16
- """
17
-
18
- def __init__(self, image_path: str, draw_location_x: int = 0, draw_location_y: int = 0):
19
- super().__init__(draw_location_x, draw_location_y)
20
- self.image_path: Path = Path(image_path)
21
-
22
- if self.image_path.exists() and self.image_path.is_file():
23
- front_engine_logger.info(f"Loading image file: {self.image_path}")
24
- self.image: QImage = QImage(str(self.image_path))
25
- self.resize(self.image.size())
26
- else:
27
- message_box: QMessageBox = QMessageBox(self)
28
- message_box.setText(language_wrapper.language_word_dict.get("paint_image_message_box_text"))
29
- message_box.show()
30
-
31
- def draw_content(self, painter: QPainter) -> None:
32
- painter.drawImage(
33
- QRect(self.draw_location_x, self.draw_location_y, self.width(), self.height()),
34
- self.image
35
- )
1
+ from pathlib import Path
2
+
3
+ from PySide6.QtCore import QRect
4
+ from PySide6.QtGui import QPainter, QImage
5
+ from PySide6.QtWidgets import QMessageBox
6
+
7
+ from frontengine.show.base_widget import BaseWidget
8
+ from frontengine.utils.logging.loggin_instance import front_engine_logger
9
+ from frontengine.utils.multi_language.language_wrapper import language_wrapper
10
+
11
+
12
+ class ImageWidget(BaseWidget):
13
+ """
14
+ ImageWidget: 顯示靜態圖片
15
+ ImageWidget: Display static image
16
+ """
17
+
18
+ def __init__(self, image_path: str, draw_location_x: int = 0, draw_location_y: int = 0):
19
+ super().__init__(draw_location_x, draw_location_y)
20
+ self.image_path: Path = Path(image_path)
21
+
22
+ if self.image_path.exists() and self.image_path.is_file():
23
+ front_engine_logger.info(f"Loading image file: {self.image_path}")
24
+ self.image: QImage = QImage(str(self.image_path))
25
+ self.resize(self.image.size())
26
+ else:
27
+ message_box: QMessageBox = QMessageBox(self)
28
+ message_box.setText(language_wrapper.language_word_dict.get("paint_image_message_box_text"))
29
+ message_box.show()
30
+
31
+ def set_image_path(self, image_path: str) -> bool:
32
+ """
33
+ 熱換顯示的圖片(用於輪播)。路徑無效時保持原圖並回傳 False。
34
+ Hot-swap the displayed image (used by the slideshow). Keeps the
35
+ current image and returns False when the path is invalid.
36
+ """
37
+ path = Path(image_path)
38
+ if not (path.exists() and path.is_file()):
39
+ front_engine_logger.warning(f"[ImageWidget] set_image_path skip invalid: {path}")
40
+ return False
41
+ self.image_path = path
42
+ self.image = QImage(str(path))
43
+ self.resize(self.image.size())
44
+ self.update()
45
+ return True
46
+
47
+ def draw_content(self, painter: QPainter) -> None:
48
+ painter.drawImage(
49
+ QRect(self.draw_location_x, self.draw_location_y, self.width(), self.height()),
50
+ self.image
51
+ )