frontengine-dev 0.0.89__tar.gz → 0.0.92__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 (160) hide show
  1. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/PKG-INFO +2 -2
  2. frontengine_dev-0.0.92/frontengine/show/base_widget.py +83 -0
  3. frontengine_dev-0.0.92/frontengine/show/gif/paint_gif.py +47 -0
  4. frontengine_dev-0.0.92/frontengine/show/image/paint_image.py +35 -0
  5. frontengine_dev-0.0.92/frontengine/show/load/load_someone_make_ui.py +68 -0
  6. frontengine_dev-0.0.92/frontengine/show/particle/particle_scene.py +134 -0
  7. frontengine_dev-0.0.92/frontengine/show/particle/particle_ui.py +80 -0
  8. frontengine_dev-0.0.92/frontengine/show/particle/particle_utils.py +120 -0
  9. frontengine_dev-0.0.92/frontengine/show/scene/extend_graphic_scene.py +32 -0
  10. frontengine_dev-0.0.92/frontengine/show/scene/extend_graphic_view.py +78 -0
  11. frontengine_dev-0.0.92/frontengine/show/scene/scene.py +120 -0
  12. frontengine_dev-0.0.92/frontengine/show/sound_player/sound_effect.py +82 -0
  13. frontengine_dev-0.0.92/frontengine/show/sound_player/sound_player.py +88 -0
  14. frontengine_dev-0.0.92/frontengine/show/text/draw_text.py +131 -0
  15. frontengine_dev-0.0.92/frontengine/show/video/video_player.py +130 -0
  16. frontengine_dev-0.0.92/frontengine/show/web/webview.py +108 -0
  17. frontengine_dev-0.0.92/frontengine/system_tray/extend_system_tray.py +77 -0
  18. frontengine_dev-0.0.92/frontengine/ui/dialog/choose_file_dialog.py +95 -0
  19. frontengine_dev-0.0.92/frontengine/ui/dialog/save_file_dialog.py +26 -0
  20. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/main_ui.py +101 -50
  21. frontengine_dev-0.0.92/frontengine/ui/menu/help_menu.py +61 -0
  22. frontengine_dev-0.0.92/frontengine/ui/menu/how_to_menu.py +44 -0
  23. frontengine_dev-0.0.92/frontengine/ui/menu/language_menu.py +57 -0
  24. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/page/control_center/control_center_ui.py +45 -75
  25. frontengine_dev-0.0.92/frontengine/ui/page/gif/gif_setting_ui.py +132 -0
  26. frontengine_dev-0.0.92/frontengine/ui/page/image/image_setting_ui.py +116 -0
  27. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/page/particle/particle_setting_ui.py +76 -83
  28. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/page/scene_setting/scene_manager.py +48 -29
  29. frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page/gif.py +87 -0
  30. frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page/image.py +72 -0
  31. frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page/sound.py +77 -0
  32. frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page/text.py +80 -0
  33. frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page/video.py +107 -0
  34. frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page/web.py +58 -0
  35. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/page/scene_setting/scene_setting_ui.py +27 -26
  36. frontengine_dev-0.0.92/frontengine/ui/page/sound_player/sound_player_setting_ui.py +111 -0
  37. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/page/text/text_setting_ui.py +50 -55
  38. frontengine_dev-0.0.92/frontengine/ui/page/utils.py +84 -0
  39. frontengine_dev-0.0.92/frontengine/ui/page/video/video_setting_ui.py +156 -0
  40. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/page/web/web_setting_ui.py +43 -48
  41. frontengine_dev-0.0.92/frontengine/user_setting/scene_setting.py +70 -0
  42. frontengine_dev-0.0.92/frontengine/user_setting/user_setting_file.py +37 -0
  43. frontengine_dev-0.0.92/frontengine/utils/browser/browser.py +21 -0
  44. frontengine_dev-0.0.92/frontengine/utils/critical_exit/check_key_is_press.py +28 -0
  45. frontengine_dev-0.0.92/frontengine/utils/critical_exit/critical_exit.py +62 -0
  46. frontengine_dev-0.0.92/frontengine/utils/file/open/open_file.py +36 -0
  47. frontengine_dev-0.0.92/frontengine/utils/file/save/save_file.py +33 -0
  48. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/json/json_file.py +2 -2
  49. frontengine_dev-0.0.92/frontengine/utils/json_format/json_process.py +42 -0
  50. frontengine_dev-0.0.92/frontengine/utils/logging/loggin_instance.py +46 -0
  51. frontengine_dev-0.0.92/frontengine/utils/redirect_manager/redirect_manager_class.py +85 -0
  52. frontengine_dev-0.0.92/frontengine/worker/qthread_worker.py +60 -0
  53. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine_dev.egg-info/PKG-INFO +2 -2
  54. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine_dev.egg-info/SOURCES.txt +1 -3
  55. frontengine_dev-0.0.92/frontengine_dev.egg-info/requires.txt +2 -0
  56. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/pyproject.toml +2 -2
  57. frontengine_dev-0.0.89/frontengine/show/clicker/clicker_scene.py +0 -10
  58. frontengine_dev-0.0.89/frontengine/show/clicker/clicker_ui.py +0 -33
  59. frontengine_dev-0.0.89/frontengine/show/gif/paint_gif.py +0 -93
  60. frontengine_dev-0.0.89/frontengine/show/image/paint_image.py +0 -76
  61. frontengine_dev-0.0.89/frontengine/show/load/load_someone_make_ui.py +0 -43
  62. frontengine_dev-0.0.89/frontengine/show/particle/particle_scene.py +0 -82
  63. frontengine_dev-0.0.89/frontengine/show/particle/particle_ui.py +0 -51
  64. frontengine_dev-0.0.89/frontengine/show/particle/particle_utils.py +0 -96
  65. frontengine_dev-0.0.89/frontengine/show/scene/extend_graphic_scene.py +0 -10
  66. frontengine_dev-0.0.89/frontengine/show/scene/extend_graphic_view.py +0 -53
  67. frontengine_dev-0.0.89/frontengine/show/scene/scene.py +0 -104
  68. frontengine_dev-0.0.89/frontengine/show/sound_player/sound_effect.py +0 -56
  69. frontengine_dev-0.0.89/frontengine/show/sound_player/sound_player.py +0 -57
  70. frontengine_dev-0.0.89/frontengine/show/text/draw_text.py +0 -106
  71. frontengine_dev-0.0.89/frontengine/show/video/video_player.py +0 -96
  72. frontengine_dev-0.0.89/frontengine/show/web/webview.py +0 -90
  73. frontengine_dev-0.0.89/frontengine/system_tray/extend_system_tray.py +0 -44
  74. frontengine_dev-0.0.89/frontengine/ui/dialog/choose_file_dialog.py +0 -95
  75. frontengine_dev-0.0.89/frontengine/ui/dialog/save_file_dialog.py +0 -19
  76. frontengine_dev-0.0.89/frontengine/ui/menu/help_menu.py +0 -48
  77. frontengine_dev-0.0.89/frontengine/ui/menu/how_to_menu.py +0 -27
  78. frontengine_dev-0.0.89/frontengine/ui/menu/language_menu.py +0 -94
  79. frontengine_dev-0.0.89/frontengine/ui/page/gif/gif_setting_ui.py +0 -155
  80. frontengine_dev-0.0.89/frontengine/ui/page/image/image_setting_ui.py +0 -137
  81. frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page/gif.py +0 -108
  82. frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page/image.py +0 -88
  83. frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page/sound.py +0 -89
  84. frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page/text.py +0 -98
  85. frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page/video.py +0 -122
  86. frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page/web.py +0 -66
  87. frontengine_dev-0.0.89/frontengine/ui/page/sound_player/sound_player_setting_ui.py +0 -126
  88. frontengine_dev-0.0.89/frontengine/ui/page/utils.py +0 -43
  89. frontengine_dev-0.0.89/frontengine/ui/page/video/video_setting_ui.py +0 -170
  90. frontengine_dev-0.0.89/frontengine/user_setting/scene_setting.py +0 -34
  91. frontengine_dev-0.0.89/frontengine/user_setting/user_setting_file.py +0 -21
  92. frontengine_dev-0.0.89/frontengine/utils/browser/browser.py +0 -5
  93. frontengine_dev-0.0.89/frontengine/utils/critical_exit/check_key_is_press.py +0 -11
  94. frontengine_dev-0.0.89/frontengine/utils/critical_exit/critical_exit.py +0 -52
  95. frontengine_dev-0.0.89/frontengine/utils/file/open/open_file.py +0 -35
  96. frontengine_dev-0.0.89/frontengine/utils/file/save/save_file.py +0 -28
  97. frontengine_dev-0.0.89/frontengine/utils/json_format/json_process.py +0 -28
  98. frontengine_dev-0.0.89/frontengine/utils/logging/loggin_instance.py +0 -26
  99. frontengine_dev-0.0.89/frontengine/utils/redirect_manager/redirect_manager_class.py +0 -74
  100. frontengine_dev-0.0.89/frontengine/worker/__init__.py +0 -0
  101. frontengine_dev-0.0.89/frontengine/worker/qthread_worker.py +0 -34
  102. frontengine_dev-0.0.89/frontengine_dev.egg-info/requires.txt +0 -2
  103. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/LICENSE +0 -0
  104. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/README.md +0 -0
  105. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/__init__.py +0 -0
  106. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/show/__init__.py +0 -0
  107. {frontengine_dev-0.0.89/frontengine/show/clicker → frontengine_dev-0.0.92/frontengine/show/gif}/__init__.py +0 -0
  108. {frontengine_dev-0.0.89/frontengine/show/gif → frontengine_dev-0.0.92/frontengine/show/image}/__init__.py +0 -0
  109. {frontengine_dev-0.0.89/frontengine/show/image → frontengine_dev-0.0.92/frontengine/show/load}/__init__.py +0 -0
  110. {frontengine_dev-0.0.89/frontengine/show/load → frontengine_dev-0.0.92/frontengine/show/particle}/__init__.py +0 -0
  111. {frontengine_dev-0.0.89/frontengine/show/particle → frontengine_dev-0.0.92/frontengine/show/scene}/__init__.py +0 -0
  112. {frontengine_dev-0.0.89/frontengine/show/scene → frontengine_dev-0.0.92/frontengine/show/sound_player}/__init__.py +0 -0
  113. {frontengine_dev-0.0.89/frontengine/show/sound_player → frontengine_dev-0.0.92/frontengine/show/text}/__init__.py +0 -0
  114. {frontengine_dev-0.0.89/frontengine/show/text → frontengine_dev-0.0.92/frontengine/show/video}/__init__.py +0 -0
  115. {frontengine_dev-0.0.89/frontengine/show/video → frontengine_dev-0.0.92/frontengine/show/web}/__init__.py +0 -0
  116. {frontengine_dev-0.0.89/frontengine/show/web → frontengine_dev-0.0.92/frontengine/system_tray}/__init__.py +0 -0
  117. {frontengine_dev-0.0.89/frontengine/system_tray → frontengine_dev-0.0.92/frontengine/ui}/__init__.py +0 -0
  118. {frontengine_dev-0.0.89/frontengine/ui → frontengine_dev-0.0.92/frontengine/ui/color}/__init__.py +0 -0
  119. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/ui/color/global_color.py +0 -0
  120. {frontengine_dev-0.0.89/frontengine/ui/color → frontengine_dev-0.0.92/frontengine/ui/dialog}/__init__.py +0 -0
  121. {frontengine_dev-0.0.89/frontengine/ui/dialog → frontengine_dev-0.0.92/frontengine/ui/menu}/__init__.py +0 -0
  122. {frontengine_dev-0.0.89/frontengine/ui/menu → frontengine_dev-0.0.92/frontengine/ui/page}/__init__.py +0 -0
  123. {frontengine_dev-0.0.89/frontengine/ui/page → frontengine_dev-0.0.92/frontengine/ui/page/control_center}/__init__.py +0 -0
  124. {frontengine_dev-0.0.89/frontengine/ui/page/control_center → frontengine_dev-0.0.92/frontengine/ui/page/gif}/__init__.py +0 -0
  125. {frontengine_dev-0.0.89/frontengine/ui/page/gif → frontengine_dev-0.0.92/frontengine/ui/page/image}/__init__.py +0 -0
  126. {frontengine_dev-0.0.89/frontengine/ui/page/image → frontengine_dev-0.0.92/frontengine/ui/page/particle}/__init__.py +0 -0
  127. {frontengine_dev-0.0.89/frontengine/ui/page/particle → frontengine_dev-0.0.92/frontengine/ui/page/scene_setting}/__init__.py +0 -0
  128. {frontengine_dev-0.0.89/frontengine/ui/page/scene_setting → frontengine_dev-0.0.92/frontengine/ui/page/scene_setting/scene_page}/__init__.py +0 -0
  129. {frontengine_dev-0.0.89/frontengine/ui/page/scene_setting/scene_page → frontengine_dev-0.0.92/frontengine/ui/page/sound_player}/__init__.py +0 -0
  130. {frontengine_dev-0.0.89/frontengine/ui/page/sound_player → frontengine_dev-0.0.92/frontengine/ui/page/text}/__init__.py +0 -0
  131. {frontengine_dev-0.0.89/frontengine/ui/page/text → frontengine_dev-0.0.92/frontengine/ui/page/video}/__init__.py +0 -0
  132. {frontengine_dev-0.0.89/frontengine/ui/page/video → frontengine_dev-0.0.92/frontengine/ui/page/web}/__init__.py +0 -0
  133. {frontengine_dev-0.0.89/frontengine/ui/page/web → frontengine_dev-0.0.92/frontengine/user_setting}/__init__.py +0 -0
  134. {frontengine_dev-0.0.89/frontengine/user_setting → frontengine_dev-0.0.92/frontengine/utils}/__init__.py +0 -0
  135. {frontengine_dev-0.0.89/frontengine/utils → frontengine_dev-0.0.92/frontengine/utils/browser}/__init__.py +0 -0
  136. {frontengine_dev-0.0.89/frontengine/utils/browser → frontengine_dev-0.0.92/frontengine/utils/critical_exit}/__init__.py +0 -0
  137. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/critical_exit/win32_vk.py +0 -0
  138. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/exception/__init__.py +0 -0
  139. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/exception/exception_tags.py +0 -0
  140. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/exception/exceptions.py +0 -0
  141. {frontengine_dev-0.0.89/frontengine/utils/critical_exit → frontengine_dev-0.0.92/frontengine/utils/file}/__init__.py +0 -0
  142. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/file/open/__init__.py +0 -0
  143. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/file/save/__init__.py +0 -0
  144. {frontengine_dev-0.0.89/frontengine/utils/file → frontengine_dev-0.0.92/frontengine/utils/json}/__init__.py +0 -0
  145. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/json_format/__init__.py +0 -0
  146. {frontengine_dev-0.0.89/frontengine/utils/json → frontengine_dev-0.0.92/frontengine/utils/logging}/__init__.py +0 -0
  147. {frontengine_dev-0.0.89/frontengine/utils/logging → frontengine_dev-0.0.92/frontengine/utils/multi_language}/__init__.py +0 -0
  148. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/english.py +0 -0
  149. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/france.py +0 -0
  150. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/germany.py +0 -0
  151. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/italy.py +0 -0
  152. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/language_wrapper.py +0 -0
  153. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/russian.py +0 -0
  154. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/simplified_chinese.py +0 -0
  155. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine/utils/multi_language/traditional_chinese.py +0 -0
  156. {frontengine_dev-0.0.89/frontengine/utils/multi_language → frontengine_dev-0.0.92/frontengine/utils/redirect_manager}/__init__.py +0 -0
  157. {frontengine_dev-0.0.89/frontengine/utils/redirect_manager → frontengine_dev-0.0.92/frontengine/worker}/__init__.py +0 -0
  158. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine_dev.egg-info/dependency_links.txt +0 -0
  159. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/frontengine_dev.egg-info/top_level.txt +0 -0
  160. {frontengine_dev-0.0.89 → frontengine_dev-0.0.92}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: frontengine_dev
3
- Version: 0.0.89
3
+ Version: 0.0.92
4
4
  Summary: FrontEngine is use-define frontview or only use like screen saver
5
5
  Author-email: JE-Chen <jechenmailman@gmail.com>
6
6
  Project-URL: Homepage, https://github.com/Intergration-Automation-Testing/FrontEngine
@@ -14,7 +14,7 @@ Classifier: Operating System :: OS Independent
14
14
  Requires-Python: >=3.10
15
15
  Description-Content-Type: text/markdown
16
16
  License-File: LICENSE
17
- Requires-Dist: PySide6==6.9.3
17
+ Requires-Dist: PySide6==6.10.0
18
18
  Requires-Dist: qt-material
19
19
  Dynamic: license-file
20
20
 
@@ -0,0 +1,83 @@
1
+ import os
2
+ from abc import abstractmethod
3
+ from pathlib import Path
4
+
5
+ from PySide6.QtCore import Qt
6
+ from PySide6.QtGui import QPainter, QIcon
7
+ from PySide6.QtWidgets import QWidget
8
+
9
+ from frontengine.utils.logging.loggin_instance import front_engine_logger
10
+
11
+
12
+ class BaseWidget(QWidget):
13
+ """
14
+ BaseWidget: 提供共用 UI 屬性與事件處理的基底類別
15
+ BaseWidget: Base class providing shared UI attributes and event handling
16
+ """
17
+
18
+ def __init__(self, draw_location_x: int = 0, draw_location_y: int = 0):
19
+ super().__init__()
20
+ self.draw_location_x: int = draw_location_x
21
+ self.draw_location_y: int = draw_location_y
22
+ self.opacity: float = 0.2
23
+
24
+ # 設定視窗屬性 / Set widget attributes
25
+ self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
26
+ self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
27
+
28
+ # 設定視窗 Icon / Set window icon
29
+ self.icon_path: Path = Path(os.getcwd()) / "je_driver_icon.ico"
30
+ if self.icon_path.exists() and self.icon_path.is_file():
31
+ self.setWindowIcon(QIcon(str(self.icon_path)))
32
+
33
+ def set_ui_window_flag(self, show_on_bottom: bool = False) -> None:
34
+ """
35
+ 設定視窗旗標 (保持最上層或最下層)
36
+ Set window flags (stay on top or bottom)
37
+ """
38
+ front_engine_logger.info(f"{self.__class__.__name__} set_ui_window_flag | show_on_bottom: {show_on_bottom}")
39
+ self.setWindowFlag(
40
+ Qt.WindowType.WindowTransparentForInput |
41
+ Qt.WindowType.FramelessWindowHint |
42
+ Qt.WindowType.Tool
43
+ )
44
+ if not show_on_bottom:
45
+ self.setWindowFlag(Qt.WindowType.WindowStaysOnTopHint)
46
+ else:
47
+ self.setWindowFlag(Qt.WindowType.WindowStaysOnBottomHint)
48
+
49
+ def set_ui_variable(self, opacity: float = 0.2) -> None:
50
+ """
51
+ 設定 UI 透明度
52
+ Set UI opacity
53
+ """
54
+ front_engine_logger.info(f"{self.__class__.__name__} set_ui_variable | opacity: {opacity}")
55
+ self.opacity = opacity
56
+
57
+ def paintEvent(self, event) -> None:
58
+ """
59
+ 呼叫子類別的繪製方法
60
+ Call subclass draw_content method
61
+ """
62
+ front_engine_logger.debug(f"{self.__class__.__name__} paintEvent | event: {event}")
63
+ painter = QPainter(self)
64
+ painter.setOpacity(self.opacity)
65
+ self.draw_content(painter)
66
+ painter.restore()
67
+
68
+ @abstractmethod
69
+ def draw_content(self, painter: QPainter) -> None:
70
+ """
71
+ 子類別必須實作的繪製方法
72
+ Subclasses must implement this drawing method
73
+ """
74
+ pass
75
+
76
+ # --- 共用滑鼠事件 / Shared mouse events ---
77
+ def mousePressEvent(self, event) -> None:
78
+ front_engine_logger.debug(f"{self.__class__.__name__} mousePressEvent | event: {event}")
79
+ super().mousePressEvent(event)
80
+
81
+ def mouseDoubleClickEvent(self, event) -> None:
82
+ front_engine_logger.debug(f"{self.__class__.__name__} mouseDoubleClickEvent | event: {event}")
83
+ super().mouseDoubleClickEvent(event)
@@ -0,0 +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
+ )
@@ -0,0 +1,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 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
+ )
@@ -0,0 +1,68 @@
1
+ from typing import Optional, List
2
+
3
+ from PySide6.QtGui import QScreen
4
+ from PySide6.QtUiTools import QUiLoader
5
+ from PySide6.QtWidgets import QWidget
6
+
7
+ from frontengine.utils.exception.exceptions import FrontEngineLoadUIException
8
+ from frontengine.utils.logging.loggin_instance import front_engine_logger
9
+
10
+
11
+ def load_extend_ui_file(ui_path: str, show_all_screen: bool = False) -> None:
12
+ """
13
+ 載入並顯示 UI 檔案
14
+ Load and display a UI file
15
+
16
+ :param ui_path: UI 檔案路徑 / Path to the UI file
17
+ :param show_all_screen: 是否顯示在所有螢幕上 / Show on all screens
18
+ """
19
+ front_engine_logger.info(
20
+ f"[load_extend_ui_file] ui_path={ui_path}, show_all_screen={show_all_screen}"
21
+ )
22
+
23
+ ui: QWidget = load_ui_file(ui_path)
24
+
25
+ if show_all_screen:
26
+ ui.showFullScreen()
27
+ else:
28
+ # 取得所有螢幕並在每個螢幕上顯示 UI
29
+ # Get all monitors and display UI on each
30
+ monitors: List[QScreen] = QScreen.virtualSiblings(ui.screen())
31
+ for screen in monitors:
32
+ monitor_geometry = screen.availableGeometry()
33
+ ui.move(monitor_geometry.left(), monitor_geometry.top())
34
+ ui.showFullScreen()
35
+
36
+
37
+ def load_ui_file(ui_path: str) -> QWidget:
38
+ """
39
+ 載入 UI 檔案
40
+ Load a UI file
41
+
42
+ :param ui_path: UI 檔案路徑 / Path to the UI file
43
+ :return: QWidget 物件 / QWidget object
44
+ :raises FrontEngineLoadUIException: 若載入失敗 / If loading fails
45
+ """
46
+ front_engine_logger.info(f"[load_ui_file] ui_path={ui_path}")
47
+ ui: QWidget = QUiLoader().load(ui_path)
48
+
49
+ if not ui:
50
+ front_engine_logger.error(f"[load_ui_file] Failed to load UI: {ui_path}")
51
+ raise FrontEngineLoadUIException(f"Failed to load UI file: {ui_path}")
52
+
53
+ return ui
54
+
55
+
56
+ def read_extend_ui(ui: QWidget) -> Optional[QWidget]:
57
+ """
58
+ 驗證並回傳 UI 物件
59
+ Validate and return UI object
60
+
61
+ :param ui: QWidget 物件 / QWidget object
62
+ :return: QWidget 或 None / QWidget or None
63
+ """
64
+ front_engine_logger.info(f"[read_extend_ui] ui={ui}")
65
+
66
+ if not isinstance(ui, QWidget):
67
+ return None
68
+ return ui
@@ -0,0 +1,134 @@
1
+ import random
2
+ from typing import Callable, Dict, Any
3
+
4
+ from PySide6.QtCore import QTimer, QPoint, QRect
5
+ from PySide6.QtGui import QPixmap
6
+ from PySide6.QtWidgets import QGraphicsScene
7
+
8
+ from frontengine.show.particle.particle_utils import (
9
+ particle_down, particle_up, particle_left, particle_right,
10
+ particle_left_down, particle_left_up, particle_right_down, particle_right_up,
11
+ particle_random_minus, particle_random_add, particle_random
12
+ )
13
+ from frontengine.utils.logging.loggin_instance import front_engine_logger
14
+
15
+
16
+ class ParticleGraphicScene(QGraphicsScene):
17
+ """
18
+ 粒子特效場景,用於顯示粒子動畫
19
+ ParticleGraphicScene: A QGraphicsScene subclass for particle animation
20
+ """
21
+
22
+ def __init__(self,
23
+ particle_pixmap: QPixmap,
24
+ particle_direction: str,
25
+ particle_count: int = 500,
26
+ screen_height: int = 1920,
27
+ screen_width: int = 1080,
28
+ opacity: float = 0.2,
29
+ particle_speed: int = 1):
30
+ """
31
+ 初始化粒子場景
32
+ Initialize particle scene
33
+
34
+ :param particle_pixmap: 粒子圖片 / Particle pixmap
35
+ :param particle_direction: 粒子移動方向 / Particle movement direction
36
+ :param particle_count: 粒子數量 / Number of particles
37
+ :param screen_height: 畫布高度 / Screen height
38
+ :param screen_width: 畫布寬度 / Screen width
39
+ :param opacity: 粒子透明度 / Particle opacity
40
+ :param particle_speed: 粒子移動速度 / Particle speed
41
+ """
42
+ front_engine_logger.info(
43
+ f"Init ParticleGraphicScene | "
44
+ f"particle_direction={particle_direction}, "
45
+ f"particle_count={particle_count}, "
46
+ f"screen_height={screen_height}, screen_width={screen_width}, "
47
+ f"opacity={opacity}, particle_speed={particle_speed}"
48
+ )
49
+ super().__init__()
50
+
51
+ # --- 基本屬性 / Basic attributes ---
52
+ self.particle_pixmap: QPixmap = particle_pixmap
53
+ self.particle_direction: str = particle_direction
54
+ self.particle_count: int = particle_count
55
+ self.opacity: float = opacity
56
+ self.particle_speed: int = particle_speed
57
+ self.screen_height: int = screen_height
58
+ self.screen_width: int = screen_width
59
+
60
+ # 儲存粒子資訊的字典 / Dictionary to store particle info
61
+ self.particle_dict: Dict[str, Dict[str, Any]] = {}
62
+
63
+ # 建立粒子 / Create particles
64
+ self.create_particle()
65
+
66
+ # 設定更新函式 / Set update function
67
+ self.update_function: Callable = {
68
+ "down": particle_down,
69
+ "up": particle_up,
70
+ "left": particle_left,
71
+ "right": particle_right,
72
+ "left_down": particle_left_down,
73
+ "left_up": particle_left_up,
74
+ "right_down": particle_right_down,
75
+ "right_up": particle_right_up,
76
+ "random_minus": particle_random_minus,
77
+ "random_add": particle_random_add,
78
+ "random": particle_random
79
+ }.get(self.particle_direction)
80
+
81
+ if not self.update_function:
82
+ front_engine_logger.error(f"Invalid particle direction: {self.particle_direction}")
83
+ raise ValueError(f"Unsupported particle direction: {self.particle_direction}")
84
+
85
+ # 設定場景大小 / Set scene size
86
+ self.setSceneRect(QRect(0, 0, screen_width, screen_height))
87
+
88
+ # 啟動定時器 / Start update timer
89
+ self.update_timer: QTimer = QTimer()
90
+ self.update_timer.setInterval(100) # 更新間隔 (毫秒) / Update interval (ms)
91
+ self.update_timer.timeout.connect(self.update_particle_xy)
92
+ self.update_timer.start()
93
+
94
+ def create_particle(self) -> None:
95
+ """
96
+ 建立粒子並隨機分布在場景中
97
+ Create particles and randomly distribute them in the scene
98
+ """
99
+ front_engine_logger.info("ParticleGraphicScene create_particle")
100
+ self.particle_dict.clear()
101
+
102
+ for count in range(self.particle_count):
103
+ item = self.addPixmap(self.particle_pixmap)
104
+ item.setOpacity(self.opacity)
105
+ self.particle_dict[f"particle_{count}"] = {
106
+ "x": random.randint(0, self.screen_width),
107
+ "y": random.randint(0, self.screen_height),
108
+ "height": self.screen_height,
109
+ "width": self.screen_width,
110
+ "pixmap_item": item,
111
+ }
112
+
113
+ def update_particle_xy(self) -> None:
114
+ """
115
+ 更新粒子座標並重新繪製
116
+ Update particle positions and redraw
117
+ """
118
+ front_engine_logger.debug("ParticleGraphicScene update_particle_xy")
119
+
120
+ # 更新粒子座標 / Update particle positions
121
+ self.update_function(self.particle_dict, self.particle_speed)
122
+
123
+ # 更新場景中的粒子位置 / Update positions in scene
124
+ for particle in self.particle_dict.values():
125
+ pixmap_item = particle["pixmap_item"]
126
+ pixmap_item.setPos(particle["x"], particle["y"])
127
+
128
+ # 如果粒子超出場景範圍,移除它 / Remove particle if out of bounds
129
+ if not self.sceneRect().contains(QPoint(particle["x"], particle["y"])):
130
+ self.removeItem(pixmap_item)
131
+
132
+ # 如果場景中沒有粒子,重新建立 / Recreate particles if all removed
133
+ if not self.items():
134
+ self.create_particle()
@@ -0,0 +1,80 @@
1
+ from PySide6.QtCore import QSize
2
+ from PySide6.QtGui import QPixmap, Qt
3
+ from PySide6.QtWidgets import QWidget, QGridLayout
4
+
5
+ from frontengine.show.particle.particle_scene import ParticleGraphicScene
6
+ from frontengine.show.scene.extend_graphic_view import ExtendGraphicView
7
+ from frontengine.utils.logging.loggin_instance import front_engine_logger
8
+
9
+
10
+ class ParticleWidget(QWidget):
11
+ """
12
+ 粒子特效顯示元件
13
+ ParticleWidget: A QWidget wrapper for displaying particle effects
14
+ """
15
+
16
+ def __init__(self,
17
+ pixmap: QPixmap,
18
+ particle_size: int,
19
+ particle_direction: str,
20
+ particle_count: int = 50,
21
+ screen_height: int = 1080,
22
+ screen_width: int = 1920,
23
+ opacity: float = 0.2,
24
+ particle_speed: int = 1):
25
+ """
26
+ 初始化粒子元件
27
+ Initialize particle widget
28
+
29
+ :param pixmap: 粒子圖片 / Particle pixmap
30
+ :param particle_size: 粒子大小 / Particle size
31
+ :param particle_direction: 粒子方向 / Particle direction
32
+ :param particle_count: 粒子數量 / Number of particles
33
+ :param screen_height: 畫布高度 / Screen height
34
+ :param screen_width: 畫布寬度 / Screen width
35
+ :param opacity: 粒子透明度 / Particle opacity
36
+ :param particle_speed: 粒子速度 / Particle speed
37
+ """
38
+ front_engine_logger.info(
39
+ f"[ParticleWidget] Init | direction={particle_direction}, "
40
+ f"count={particle_count}, size={particle_size}, "
41
+ f"screen=({screen_width}x{screen_height}), opacity={opacity}, speed={particle_speed}"
42
+ )
43
+ super().__init__()
44
+
45
+ # 設定視窗屬性 / Set widget attributes
46
+ self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
47
+ self.setAttribute(Qt.WidgetAttribute.WA_DeleteOnClose)
48
+
49
+ # --- 設定粒子圖片大小 / Scale particle pixmap ---
50
+ target_size = QSize(particle_size, particle_size) if particle_size else QSize(pixmap.width(), pixmap.height())
51
+ self.pixmap: QPixmap = pixmap.scaled(target_size, Qt.AspectRatioMode.KeepAspectRatio)
52
+
53
+ # --- 建立場景與視圖 / Create scene and view ---
54
+ self.particle_view: ExtendGraphicView = ExtendGraphicView()
55
+ self.particle_scene: ParticleGraphicScene = ParticleGraphicScene(
56
+ self.pixmap, particle_direction, particle_count,
57
+ screen_height, screen_width, opacity, particle_speed
58
+ )
59
+ self.particle_view.setScene(self.particle_scene)
60
+
61
+ # --- 設定版面配置 / Set layout ---
62
+ self.grid_layout: QGridLayout = QGridLayout()
63
+ self.grid_layout.addWidget(self.particle_view, 0, 0, -1, -1)
64
+ self.setLayout(self.grid_layout)
65
+
66
+ def set_ui_window_flag(self, show_on_bottom: bool = False) -> None:
67
+ """
68
+ 設定視窗旗標 (保持最上層或最下層)
69
+ Set window flags (stay on top or bottom)
70
+ """
71
+ front_engine_logger.info(f"[ParticleWidget] set_ui_window_flag | show_on_bottom={show_on_bottom}")
72
+ self.setWindowFlag(
73
+ Qt.WindowType.WindowTransparentForInput |
74
+ Qt.WindowType.FramelessWindowHint |
75
+ Qt.WindowType.Tool
76
+ )
77
+ if not show_on_bottom:
78
+ self.setWindowFlag(Qt.WindowType.WindowStaysOnTopHint)
79
+ else:
80
+ self.setWindowFlag(Qt.WindowType.WindowStaysOnBottomHint)
@@ -0,0 +1,120 @@
1
+ import random
2
+ from typing import Dict, Callable
3
+
4
+ from frontengine.utils.logging.loggin_instance import front_engine_logger
5
+
6
+
7
+ def particle_down(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
8
+ """
9
+ 粒子向下移動
10
+ Move particles downward
11
+ """
12
+ front_engine_logger.debug(f"[particle_down] speed={particle_speed}, count={len(particle_dict)}")
13
+ for particle in particle_dict.values():
14
+ particle["y"] = particle.get("y", 0) + random.randint(0, particle_speed)
15
+
16
+
17
+ def particle_up(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
18
+ """
19
+ 粒子向上移動
20
+ Move particles upward
21
+ """
22
+ front_engine_logger.debug(f"[particle_up] speed={particle_speed}, count={len(particle_dict)}")
23
+ for particle in particle_dict.values():
24
+ particle["y"] = particle.get("y", 0) - random.randint(0, particle_speed)
25
+
26
+
27
+ def particle_left(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
28
+ """
29
+ 粒子向左移動
30
+ Move particles left
31
+ """
32
+ front_engine_logger.debug(f"[particle_left] speed={particle_speed}, count={len(particle_dict)}")
33
+ for particle in particle_dict.values():
34
+ particle["x"] = particle.get("x", 0) - random.randint(0, particle_speed)
35
+
36
+
37
+ def particle_right(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
38
+ """
39
+ 粒子向右移動
40
+ Move particles right
41
+ """
42
+ front_engine_logger.debug(f"[particle_right] speed={particle_speed}, count={len(particle_dict)}")
43
+ for particle in particle_dict.values():
44
+ particle["x"] = particle.get("x", 0) + random.randint(0, particle_speed)
45
+
46
+
47
+ def particle_left_down(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
48
+ """
49
+ 粒子向左下移動
50
+ Move particles left and down
51
+ """
52
+ front_engine_logger.debug(f"[particle_left_down] speed={particle_speed}")
53
+ particle_left(particle_dict, particle_speed)
54
+ particle_down(particle_dict, particle_speed)
55
+
56
+
57
+ def particle_left_up(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
58
+ """
59
+ 粒子向左上移動
60
+ Move particles left and up
61
+ """
62
+ front_engine_logger.debug(f"[particle_left_up] speed={particle_speed}")
63
+ particle_left(particle_dict, particle_speed)
64
+ particle_up(particle_dict, particle_speed)
65
+
66
+
67
+ def particle_right_down(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
68
+ """
69
+ 粒子向右下移動
70
+ Move particles right and down
71
+ """
72
+ front_engine_logger.debug(f"[particle_right_down] speed={particle_speed}")
73
+ particle_right(particle_dict, particle_speed)
74
+ particle_down(particle_dict, particle_speed)
75
+
76
+
77
+ def particle_right_up(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
78
+ """
79
+ 粒子向右上移動
80
+ Move particles right and up
81
+ """
82
+ front_engine_logger.debug(f"[particle_right_up] speed={particle_speed}")
83
+ particle_right(particle_dict, particle_speed)
84
+ particle_up(particle_dict, particle_speed)
85
+
86
+
87
+ def particle_random_minus(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
88
+ """
89
+ 粒子隨機往左下移動
90
+ Move particles randomly left and down
91
+ """
92
+ front_engine_logger.debug(f"[particle_random_minus] speed={particle_speed}")
93
+ for particle in particle_dict.values():
94
+ particle["y"] = particle.get("y", 0) + random.randint(0, particle_speed)
95
+ particle["x"] = particle.get("x", 0) - random.randint(0, particle_speed)
96
+
97
+
98
+ def particle_random_add(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
99
+ """
100
+ 粒子隨機往右上移動
101
+ Move particles randomly right and up
102
+ """
103
+ front_engine_logger.debug(f"[particle_random_add] speed={particle_speed}")
104
+ for particle in particle_dict.values():
105
+ particle["y"] = particle.get("y", 0) - random.randint(0, particle_speed)
106
+ particle["x"] = particle.get("x", 0) + random.randint(0, particle_speed)
107
+
108
+
109
+ def particle_random(particle_dict: Dict[str, dict], particle_speed: int = 30) -> None:
110
+ """
111
+ 粒子隨機選擇一種方向移動
112
+ Move particles in a random direction
113
+ """
114
+ front_engine_logger.debug(f"[particle_random] speed={particle_speed}")
115
+ function: Callable = random.choice([
116
+ particle_down, particle_up, particle_left, particle_right,
117
+ particle_right_up, particle_left_down, particle_left_up, particle_right_down,
118
+ particle_random_add, particle_random_minus
119
+ ])
120
+ function(particle_dict, particle_speed)
@@ -0,0 +1,32 @@
1
+ from PySide6.QtGui import QBrush, QColor
2
+ from PySide6.QtWidgets import QGraphicsScene
3
+
4
+ from frontengine.utils.logging.loggin_instance import front_engine_logger
5
+
6
+
7
+ class ExtendGraphicScene(QGraphicsScene):
8
+ """
9
+ ExtendGraphicScene: 可擴展的 QGraphicsScene 基底類別
10
+ ExtendGraphicScene: A base class extending QGraphicsScene for custom scenes
11
+ """
12
+
13
+ def __init__(self, background_color: QColor = QColor(0, 0, 0, 0)):
14
+ """
15
+ 初始化場景
16
+ Initialize the scene
17
+
18
+ :param background_color: 場景背景顏色 (預設透明) / Scene background color (default transparent)
19
+ """
20
+ front_engine_logger.info("Init ExtendGraphicScene")
21
+ super().__init__()
22
+
23
+ # 設定背景顏色 / Set background color
24
+ self.setBackgroundBrush(QBrush(background_color))
25
+
26
+ def clear_scene(self) -> None:
27
+ """
28
+ 清除場景內所有項目
29
+ Clear all items in the scene
30
+ """
31
+ front_engine_logger.debug("ExtendGraphicScene clear_scene")
32
+ self.clear()