frontengine 1.0.8__tar.gz → 1.0.10__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.
- {frontengine-1.0.8 → frontengine-1.0.10}/PKG-INFO +1 -1
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/pet/desktop_pet.py +183 -30
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/pet/pet_setting_ui.py +25 -1
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/multi_language/english.py +2 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/multi_language/traditional_chinese.py +2 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine.egg-info/PKG-INFO +1 -1
- {frontengine-1.0.8 → frontengine-1.0.10}/pyproject.toml +1 -1
- {frontengine-1.0.8 → frontengine-1.0.10}/LICENSE +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/README.md +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/__main__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/base_widget.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/gif/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/gif/paint_gif.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/image/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/image/paint_image.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/load/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/load/load_someone_make_ui.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/overlay_factory.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/particle/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/particle/particle_ui.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/pet/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/scene/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/scene/extend_graphic_scene.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/scene/extend_graphic_view.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/scene/scene.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/sound_player/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/sound_player/sound_effect.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/sound_player/sound_player.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/text/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/text/draw_text.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/video/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/video/video_player.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/web/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/web/webview.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/show/window_helpers.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/system_tray/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/system_tray/extend_system_tray.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/color/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/color/global_color.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/dialog/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/dialog/choose_file_dialog.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/dialog/hotkey_settings_dialog.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/dialog/save_file_dialog.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/main_ui.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/menu/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/menu/help_menu.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/menu/how_to_menu.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/menu/language_menu.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/menu/preset_menu.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/menu/settings_menu.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/control_center/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/control_center/control_center_ui.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/gif/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/gif/gif_setting_ui.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/image/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/image/image_setting_ui.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/particle/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/particle/particle_setting_ui.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/pet/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_manager.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/base_scene_page.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/gif.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/image.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/registry.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/sound.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/text.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/video.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/web.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_setting_ui.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/sound_player/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/sound_player/sound_player_setting_ui.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/text/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/text/text_setting_ui.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/utils.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/video/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/video/video_setting_ui.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/web/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/web/web_setting_ui.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/user_setting/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/user_setting/preset_repository.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/user_setting/scene_setting.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/user_setting/user_setting_file.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/browser/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/browser/browser.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/critical_exit/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/critical_exit/check_key_is_press.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/critical_exit/critical_exit.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/critical_exit/win32_vk.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/exception/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/exception/exception_tags.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/exception/exceptions.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/file/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/file/open/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/file/open/open_file.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/file/save/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/file/save/save_file.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/hotkey/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/hotkey/hotkey_service.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/json/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/json/json_file.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/json/json_repository.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/json_format/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/json_format/json_process.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/logging/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/logging/loggin_instance.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/multi_language/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/multi_language/france.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/multi_language/germany.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/multi_language/italy.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/multi_language/language_wrapper.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/multi_language/russian.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/multi_language/simplified_chinese.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/preset_schedule/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/preset_schedule/preset_schedule_service.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/redirect_manager/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/redirect_manager/redirect_manager_class.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/smart_pause/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/smart_pause/smart_pause_service.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/theme_schedule/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/theme_schedule/theme_schedule_service.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/web_url.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/worker/__init__.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine/worker/qthread_worker.py +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine.egg-info/SOURCES.txt +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine.egg-info/dependency_links.txt +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine.egg-info/entry_points.txt +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine.egg-info/requires.txt +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/frontengine.egg-info/top_level.txt +0 -0
- {frontengine-1.0.8 → frontengine-1.0.10}/setup.cfg +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frontengine
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.10
|
|
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
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import random as _random_module
|
|
2
|
+
import sys
|
|
2
3
|
from datetime import datetime
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
from typing import Optional, Tuple
|
|
5
6
|
|
|
6
|
-
from PySide6.QtCore import Qt, QRect, QTimer, Signal
|
|
7
|
+
from PySide6.QtCore import Qt, QRect, QTimer, QUrl, Signal
|
|
7
8
|
from PySide6.QtGui import QAction, QColor, QCursor, QFont, QFontMetrics, QMovie, QPainter, QPixmap, QTransform
|
|
9
|
+
from PySide6.QtMultimedia import QSoundEffect
|
|
8
10
|
from PySide6.QtWidgets import QMenu, QMessageBox, QWidget
|
|
9
11
|
|
|
10
12
|
from frontengine.show.base_widget import BaseWidget
|
|
@@ -95,6 +97,53 @@ def derive_visual_state(dragging: bool, airborne: bool, surface: str, motion_sta
|
|
|
95
97
|
return STATE_WALK
|
|
96
98
|
|
|
97
99
|
|
|
100
|
+
# 列舉可站立視窗時要略過的外殼視窗類別
|
|
101
|
+
# Shell window classes skipped when enumerating standable windows.
|
|
102
|
+
_PLATFORM_SKIP_CLASSES = {"WorkerW", "Progman", "Shell_TrayWnd", "Button"}
|
|
103
|
+
|
|
104
|
+
|
|
105
|
+
def windows_platforms(exclude_hwnds=()) -> list:
|
|
106
|
+
"""
|
|
107
|
+
回傳目前可見頂層視窗的上緣做為可站立平台 (left, right, top_y)。僅 Windows
|
|
108
|
+
有效,其餘平台或發生錯誤時回傳空清單。
|
|
109
|
+
Return the top edges of visible top-level windows as standable platforms
|
|
110
|
+
(left, right, top_y). Windows only; returns [] elsewhere or on error.
|
|
111
|
+
"""
|
|
112
|
+
if sys.platform != "win32":
|
|
113
|
+
return []
|
|
114
|
+
try:
|
|
115
|
+
import ctypes
|
|
116
|
+
from ctypes import wintypes
|
|
117
|
+
|
|
118
|
+
user32 = ctypes.windll.user32
|
|
119
|
+
exclude = {int(h) for h in exclude_hwnds}
|
|
120
|
+
platforms: list = []
|
|
121
|
+
|
|
122
|
+
@ctypes.WINFUNCTYPE(wintypes.BOOL, wintypes.HWND, wintypes.LPARAM)
|
|
123
|
+
def _collect(hwnd, _lparam):
|
|
124
|
+
if int(hwnd) in exclude or not user32.IsWindowVisible(hwnd):
|
|
125
|
+
return True
|
|
126
|
+
rect = wintypes.RECT()
|
|
127
|
+
if not user32.GetWindowRect(hwnd, ctypes.byref(rect)):
|
|
128
|
+
return True
|
|
129
|
+
width = rect.right - rect.left
|
|
130
|
+
height = rect.bottom - rect.top
|
|
131
|
+
if width < 80 or height < 40:
|
|
132
|
+
return True
|
|
133
|
+
class_buffer = ctypes.create_unicode_buffer(64)
|
|
134
|
+
user32.GetClassNameW(hwnd, class_buffer, 64)
|
|
135
|
+
if class_buffer.value in _PLATFORM_SKIP_CLASSES:
|
|
136
|
+
return True
|
|
137
|
+
platforms.append((rect.left, rect.right, rect.top))
|
|
138
|
+
return True
|
|
139
|
+
|
|
140
|
+
user32.EnumWindows(_collect, 0)
|
|
141
|
+
return platforms
|
|
142
|
+
except Exception as error: # pragma: no cover - Win32 boundary
|
|
143
|
+
front_engine_logger.warning(f"[windows_platforms] error: {error!r}")
|
|
144
|
+
return []
|
|
145
|
+
|
|
146
|
+
|
|
98
147
|
def message_bucket(hour: int) -> str:
|
|
99
148
|
"""依小時回傳時段 / Time-of-day bucket for the given hour."""
|
|
100
149
|
hour = int(hour) % 24
|
|
@@ -251,6 +300,12 @@ class PetMotion:
|
|
|
251
300
|
self.asleep = False
|
|
252
301
|
self.climb = bool(climb)
|
|
253
302
|
self.surface = SURFACE_FLOOR
|
|
303
|
+
# 可站立的視窗平台 (left, right, top_y);站在平台上時的狀態
|
|
304
|
+
# Standable window platforms (left, right, top_y) and platform state.
|
|
305
|
+
self.platforms: list = []
|
|
306
|
+
self.on_platform = False
|
|
307
|
+
self.platform_span: Optional[Tuple[float, float]] = None
|
|
308
|
+
self.ground_feet = 0.0
|
|
254
309
|
|
|
255
310
|
@property
|
|
256
311
|
def facing_left(self) -> bool:
|
|
@@ -259,6 +314,10 @@ class PetMotion:
|
|
|
259
314
|
def set_bounds(self, bounds: Tuple[int, int, int, int]) -> None:
|
|
260
315
|
self.bounds = bounds
|
|
261
316
|
|
|
317
|
+
def set_platforms(self, platforms) -> None:
|
|
318
|
+
"""設定可站立的視窗上緣平台 / Set standable window top-edge platforms."""
|
|
319
|
+
self.platforms = list(platforms)
|
|
320
|
+
|
|
262
321
|
def set_target(self, x: float, y: float) -> None:
|
|
263
322
|
self.target = (float(x), float(y))
|
|
264
323
|
|
|
@@ -269,6 +328,8 @@ class PetMotion:
|
|
|
269
328
|
self._airborne = True
|
|
270
329
|
self.asleep = False
|
|
271
330
|
self.surface = SURFACE_FLOOR
|
|
331
|
+
self.on_platform = False
|
|
332
|
+
self.platform_span = None
|
|
272
333
|
|
|
273
334
|
def step(self) -> Tuple[int, int]:
|
|
274
335
|
left, top, right, bottom = self.bounds
|
|
@@ -279,38 +340,19 @@ class PetMotion:
|
|
|
279
340
|
return self._step_wander(left, top, right, bottom)
|
|
280
341
|
return self._step_floor(left, top, right, bottom, floor_y)
|
|
281
342
|
|
|
282
|
-
# --- floor / gravity / climbing ---
|
|
343
|
+
# --- floor / gravity / climbing / window platforms ---
|
|
283
344
|
def _step_floor(self, left, top, right, bottom, floor_y) -> Tuple[int, int]:
|
|
284
|
-
airborne = self._airborne or (
|
|
345
|
+
airborne = self._airborne or (
|
|
346
|
+
not self.on_platform and self.surface == SURFACE_FLOOR and self.y < floor_y - 0.5
|
|
347
|
+
)
|
|
285
348
|
if airborne:
|
|
286
|
-
self.
|
|
287
|
-
|
|
288
|
-
self.
|
|
289
|
-
if self.x <= left:
|
|
290
|
-
self.x = float(left)
|
|
291
|
-
self.vx = abs(self.vx) * self.WALL_DAMPING
|
|
292
|
-
elif self.x + self.width >= right:
|
|
293
|
-
self.x = float(right - self.width)
|
|
294
|
-
self.vx = -abs(self.vx) * self.WALL_DAMPING
|
|
295
|
-
if self.y <= top:
|
|
296
|
-
self.y = float(top)
|
|
297
|
-
self.vy = abs(self.vy) * self.WALL_DAMPING
|
|
298
|
-
if self.y >= floor_y:
|
|
299
|
-
self.y = float(floor_y)
|
|
300
|
-
if abs(self.vy) > self.BOUNCE_THRESHOLD:
|
|
301
|
-
self.vy = -self.vy * self.BOUNCE_DAMPING
|
|
302
|
-
else:
|
|
303
|
-
self.vy = 0.0
|
|
304
|
-
self._airborne = False
|
|
305
|
-
self.surface = SURFACE_FLOOR
|
|
306
|
-
self.vx = float(self.speed) if self.vx >= 0 else float(-self.speed)
|
|
307
|
-
self._new_state(force_walk=True)
|
|
308
|
-
return int(self.x), int(self.y)
|
|
309
|
-
|
|
349
|
+
return self._step_fall(left, top, right, bottom, floor_y)
|
|
350
|
+
if self.on_platform:
|
|
351
|
+
return self._step_platform(left, top, right, bottom, floor_y)
|
|
310
352
|
if self.surface != SURFACE_FLOOR:
|
|
311
353
|
return self._step_climb(left, top, right, bottom, floor_y)
|
|
312
354
|
|
|
313
|
-
# grounded on the floor: random walk / idle, with a chance to climb a wall
|
|
355
|
+
# grounded on the screen floor: random walk / idle, with a chance to climb a wall
|
|
314
356
|
self.y = float(floor_y)
|
|
315
357
|
if self._state_ticks <= 0:
|
|
316
358
|
self._new_state()
|
|
@@ -334,6 +376,84 @@ class PetMotion:
|
|
|
334
376
|
self.vx = -abs(self.vx)
|
|
335
377
|
return int(self.x), int(self.y)
|
|
336
378
|
|
|
379
|
+
def _step_fall(self, left, top, right, bottom, floor_y) -> Tuple[int, int]:
|
|
380
|
+
"""落下:撞牆/天花板反彈,並在越過視窗平台或螢幕地板時落地。"""
|
|
381
|
+
prev_feet = self.y + self.height
|
|
382
|
+
self.vy += self.GRAVITY
|
|
383
|
+
self.x += self.vx
|
|
384
|
+
self.y += self.vy
|
|
385
|
+
if self.x <= left:
|
|
386
|
+
self.x = float(left)
|
|
387
|
+
self.vx = abs(self.vx) * self.WALL_DAMPING
|
|
388
|
+
elif self.x + self.width >= right:
|
|
389
|
+
self.x = float(right - self.width)
|
|
390
|
+
self.vx = -abs(self.vx) * self.WALL_DAMPING
|
|
391
|
+
if self.y <= top:
|
|
392
|
+
self.y = float(top)
|
|
393
|
+
self.vy = abs(self.vy) * self.WALL_DAMPING
|
|
394
|
+
new_feet = self.y + self.height
|
|
395
|
+
center_x = self.x + self.width / 2.0
|
|
396
|
+
|
|
397
|
+
land_feet = None
|
|
398
|
+
land_span = None
|
|
399
|
+
for platform_left, platform_right, platform_y in self.platforms:
|
|
400
|
+
if platform_left <= center_x <= platform_right and prev_feet <= platform_y <= new_feet:
|
|
401
|
+
if land_feet is None or platform_y < land_feet:
|
|
402
|
+
land_feet = float(platform_y)
|
|
403
|
+
land_span = (float(platform_left), float(platform_right))
|
|
404
|
+
if prev_feet <= bottom <= new_feet and (land_feet is None or bottom < land_feet):
|
|
405
|
+
land_feet = float(bottom)
|
|
406
|
+
land_span = None
|
|
407
|
+
|
|
408
|
+
if land_feet is not None:
|
|
409
|
+
self.y = float(land_feet - self.height)
|
|
410
|
+
if abs(self.vy) > self.BOUNCE_THRESHOLD:
|
|
411
|
+
self.vy = -self.vy * self.BOUNCE_DAMPING
|
|
412
|
+
else:
|
|
413
|
+
self.vy = 0.0
|
|
414
|
+
self._airborne = False
|
|
415
|
+
self.surface = SURFACE_FLOOR
|
|
416
|
+
self.on_platform = land_span is not None
|
|
417
|
+
self.platform_span = land_span
|
|
418
|
+
self.ground_feet = land_feet
|
|
419
|
+
self.vx = float(self.speed) if self.vx >= 0 else float(-self.speed)
|
|
420
|
+
self._new_state(force_walk=True)
|
|
421
|
+
return int(self.x), int(self.y)
|
|
422
|
+
|
|
423
|
+
def _platform_under(self) -> Optional[Tuple[float, float]]:
|
|
424
|
+
"""回傳目前站立平台的水平範圍;平台已消失(視窗移走/關閉)則回傳 None。"""
|
|
425
|
+
body_left = self.x
|
|
426
|
+
body_right = self.x + self.width
|
|
427
|
+
for platform_left, platform_right, platform_y in self.platforms:
|
|
428
|
+
if abs(platform_y - self.ground_feet) <= 2.0 and not (platform_right < body_left or platform_left > body_right):
|
|
429
|
+
return (float(platform_left), float(platform_right))
|
|
430
|
+
return None
|
|
431
|
+
|
|
432
|
+
def _step_platform(self, left, top, right, bottom, floor_y) -> Tuple[int, int]:
|
|
433
|
+
"""站在視窗平台上走動;到平台兩端轉向;平台消失則掉落。"""
|
|
434
|
+
span = self._platform_under()
|
|
435
|
+
if span is None:
|
|
436
|
+
self._airborne = True
|
|
437
|
+
self.on_platform = False
|
|
438
|
+
self.platform_span = None
|
|
439
|
+
return self._step_fall(left, top, right, bottom, floor_y)
|
|
440
|
+
self.platform_span = span
|
|
441
|
+
span_left, span_right = span
|
|
442
|
+
self.y = float(self.ground_feet - self.height)
|
|
443
|
+
if self._state_ticks <= 0:
|
|
444
|
+
self._new_state()
|
|
445
|
+
self._state_ticks -= 1
|
|
446
|
+
if self.state != "walk":
|
|
447
|
+
return int(self.x), int(self.y)
|
|
448
|
+
self.x += self.vx
|
|
449
|
+
if self.x <= span_left:
|
|
450
|
+
self.x = float(span_left)
|
|
451
|
+
self.vx = abs(self.vx)
|
|
452
|
+
elif self.x + self.width >= span_right:
|
|
453
|
+
self.x = float(span_right - self.width)
|
|
454
|
+
self.vx = -abs(self.vx)
|
|
455
|
+
return int(self.x), int(self.y)
|
|
456
|
+
|
|
337
457
|
def _step_climb(self, left, top, right, bottom, floor_y) -> Tuple[int, int]:
|
|
338
458
|
"""沿螢幕邊緣爬行;隨機放手則掉落 / Crawl the screen perimeter; may let go and fall."""
|
|
339
459
|
if self._rng.random() < self.DROP_CHANCE:
|
|
@@ -451,10 +571,12 @@ class DesktopPetWidget(BaseWidget):
|
|
|
451
571
|
clone_requested = Signal()
|
|
452
572
|
|
|
453
573
|
def __init__(self, image_path: str, size: int = 128, speed: int = 3,
|
|
454
|
-
behaviour: str = BEHAVIOUR_FLOOR, climb: bool = True, talk: bool = True
|
|
574
|
+
behaviour: str = BEHAVIOUR_FLOOR, climb: bool = True, talk: bool = True,
|
|
575
|
+
sound_path: Optional[str] = None, sit_on_windows: bool = True):
|
|
455
576
|
front_engine_logger.info(
|
|
456
577
|
f"[DesktopPetWidget] Init | path={image_path}, size={size}, speed={speed}, "
|
|
457
|
-
f"behaviour={behaviour}, climb={climb}, talk={talk}"
|
|
578
|
+
f"behaviour={behaviour}, climb={climb}, talk={talk}, sound={sound_path}, "
|
|
579
|
+
f"sit_on_windows={sit_on_windows}"
|
|
458
580
|
)
|
|
459
581
|
super().__init__()
|
|
460
582
|
self.opacity = 1.0
|
|
@@ -490,6 +612,10 @@ class DesktopPetWidget(BaseWidget):
|
|
|
490
612
|
self._chatter_rng = _random_module.SystemRandom()
|
|
491
613
|
self._mood = PetMood(user_setting_dict.get("pet_mood", 60))
|
|
492
614
|
self._messages = self._load_messages()
|
|
615
|
+
self._sound: Optional[QSoundEffect] = None
|
|
616
|
+
self._init_sound(sound_path)
|
|
617
|
+
self._sit_on_windows = bool(sit_on_windows)
|
|
618
|
+
self._platform_tick = 0
|
|
493
619
|
self._bubble = SpeechBubble()
|
|
494
620
|
self._chatter_timer = QTimer(self)
|
|
495
621
|
self._chatter_timer.setSingleShot(True)
|
|
@@ -592,6 +718,27 @@ class DesktopPetWidget(BaseWidget):
|
|
|
592
718
|
def _persist_mood(self) -> None:
|
|
593
719
|
user_setting_dict["pet_mood"] = self._mood.value
|
|
594
720
|
|
|
721
|
+
def _init_sound(self, sound_path: Optional[str]) -> None:
|
|
722
|
+
if not sound_path:
|
|
723
|
+
return
|
|
724
|
+
path = Path(sound_path)
|
|
725
|
+
if not (path.exists() and path.is_file()):
|
|
726
|
+
return
|
|
727
|
+
try:
|
|
728
|
+
self._sound = QSoundEffect(self)
|
|
729
|
+
self._sound.setSource(QUrl.fromLocalFile(str(path)))
|
|
730
|
+
except Exception as error: # pragma: no cover - audio backend guard
|
|
731
|
+
front_engine_logger.warning(f"[DesktopPetWidget] sound load failed: {error!r}")
|
|
732
|
+
self._sound = None
|
|
733
|
+
|
|
734
|
+
def _play_sound(self) -> None:
|
|
735
|
+
if self._sound is None:
|
|
736
|
+
return
|
|
737
|
+
try:
|
|
738
|
+
self._sound.play()
|
|
739
|
+
except Exception as error: # pragma: no cover - audio backend guard
|
|
740
|
+
front_engine_logger.warning(f"[DesktopPetWidget] sound play failed: {error!r}")
|
|
741
|
+
|
|
595
742
|
def _schedule_chatter(self) -> None:
|
|
596
743
|
if self._talk:
|
|
597
744
|
self._chatter_timer.start(self._chatter_rng.randint(15000, 35000))
|
|
@@ -620,6 +767,11 @@ class DesktopPetWidget(BaseWidget):
|
|
|
620
767
|
if self.motion.behaviour == BEHAVIOUR_CHASE:
|
|
621
768
|
cursor = QCursor.pos()
|
|
622
769
|
self.motion.set_target(cursor.x(), cursor.y())
|
|
770
|
+
elif self._sit_on_windows and self.motion.behaviour == BEHAVIOUR_FLOOR:
|
|
771
|
+
self._platform_tick += 1
|
|
772
|
+
if self._platform_tick >= 10:
|
|
773
|
+
self._platform_tick = 0
|
|
774
|
+
self.motion.set_platforms(windows_platforms(exclude_hwnds=(int(self.winId()),)))
|
|
623
775
|
x, y = self.motion.step()
|
|
624
776
|
self.move(x, y)
|
|
625
777
|
self._set_active_sprite(self._visual_state())
|
|
@@ -636,6 +788,7 @@ class DesktopPetWidget(BaseWidget):
|
|
|
636
788
|
self.motion.wake() # interacting wakes a sleeping pet
|
|
637
789
|
self._mood.pet() # petting cheers it up
|
|
638
790
|
self._persist_mood()
|
|
791
|
+
self._play_sound()
|
|
639
792
|
self._set_active_sprite(STATE_DRAG)
|
|
640
793
|
super().mousePressEvent(event)
|
|
641
794
|
|
|
@@ -8,7 +8,7 @@ from PySide6.QtWidgets import (
|
|
|
8
8
|
from frontengine.show.pet.desktop_pet import (
|
|
9
9
|
DesktopPetWidget, BEHAVIOUR_FLOOR, BEHAVIOUR_WANDER, BEHAVIOUR_CHASE, scan_pet_pack,
|
|
10
10
|
)
|
|
11
|
-
from frontengine.ui.dialog.choose_file_dialog import choose_pet
|
|
11
|
+
from frontengine.ui.dialog.choose_file_dialog import choose_pet, choose_wav_sound
|
|
12
12
|
from frontengine.ui.page.utils import (
|
|
13
13
|
build_recent_combobox,
|
|
14
14
|
enable_file_drop,
|
|
@@ -32,6 +32,7 @@ class PetSettingUI(QWidget):
|
|
|
32
32
|
self.pet_list: list = []
|
|
33
33
|
self.ready_to_play = False
|
|
34
34
|
self.pet_image_path: Optional[str] = None
|
|
35
|
+
self.pet_sound_path: Optional[str] = None
|
|
35
36
|
|
|
36
37
|
# Choose file
|
|
37
38
|
self.choose_file_button = QPushButton(
|
|
@@ -42,6 +43,10 @@ class PetSettingUI(QWidget):
|
|
|
42
43
|
language_wrapper.language_word_dict.get("pet_choose_pack", "Choose pet pack...")
|
|
43
44
|
)
|
|
44
45
|
self.choose_pack_button.clicked.connect(self.choose_pack)
|
|
46
|
+
self.choose_sound_button = QPushButton(
|
|
47
|
+
language_wrapper.language_word_dict.get("pet_choose_sound", "Choose sound (optional)")
|
|
48
|
+
)
|
|
49
|
+
self.choose_sound_button.clicked.connect(self.choose_sound)
|
|
45
50
|
self.ready_label = QLabel(language_wrapper.language_word_dict.get("Not Ready"))
|
|
46
51
|
|
|
47
52
|
# Size
|
|
@@ -71,6 +76,8 @@ class PetSettingUI(QWidget):
|
|
|
71
76
|
self.climb_checkbox.setChecked(True)
|
|
72
77
|
self.talk_checkbox = QCheckBox(language_wrapper.language_word_dict.get("pet_talk_label", "Speech bubbles"))
|
|
73
78
|
self.talk_checkbox.setChecked(True)
|
|
79
|
+
self.sit_checkbox = QCheckBox(language_wrapper.language_word_dict.get("pet_sit_label", "Sit on windows"))
|
|
80
|
+
self.sit_checkbox.setChecked(True)
|
|
74
81
|
|
|
75
82
|
# Start
|
|
76
83
|
self.start_button = QPushButton(language_wrapper.language_word_dict.get("pet_start", "Spawn pet"))
|
|
@@ -88,6 +95,7 @@ class PetSettingUI(QWidget):
|
|
|
88
95
|
self.grid_layout.addWidget(self.choose_file_button, 0, 0)
|
|
89
96
|
self.grid_layout.addWidget(self.ready_label, 0, 1)
|
|
90
97
|
self.grid_layout.addWidget(self.choose_pack_button, 0, 2)
|
|
98
|
+
self.grid_layout.addWidget(self.choose_sound_button, 1, 2)
|
|
91
99
|
self.grid_layout.addWidget(self.size_label, 1, 0)
|
|
92
100
|
self.grid_layout.addWidget(self.size_combobox, 1, 1)
|
|
93
101
|
self.grid_layout.addWidget(self.speed_label, 2, 0)
|
|
@@ -96,6 +104,7 @@ class PetSettingUI(QWidget):
|
|
|
96
104
|
self.grid_layout.addWidget(self.behaviour_combobox, 3, 1)
|
|
97
105
|
self.grid_layout.addWidget(self.climb_checkbox, 3, 2)
|
|
98
106
|
self.grid_layout.addWidget(self.talk_checkbox, 2, 2)
|
|
107
|
+
self.grid_layout.addWidget(self.sit_checkbox, 4, 2)
|
|
99
108
|
self.grid_layout.addWidget(self.start_button, 4, 0)
|
|
100
109
|
self.grid_layout.addWidget(self.recent_files_label, 5, 0)
|
|
101
110
|
self.grid_layout.addWidget(self.recent_files_combobox, 5, 1)
|
|
@@ -111,6 +120,8 @@ class PetSettingUI(QWidget):
|
|
|
111
120
|
behaviour=self.behaviour_combobox.currentData(),
|
|
112
121
|
climb=self.climb_checkbox.isChecked(),
|
|
113
122
|
talk=self.talk_checkbox.isChecked(),
|
|
123
|
+
sound_path=self.pet_sound_path,
|
|
124
|
+
sit_on_windows=self.sit_checkbox.isChecked(),
|
|
114
125
|
)
|
|
115
126
|
pet.clone_requested.connect(self._spawn_pet)
|
|
116
127
|
pet.set_pet_window_flag()
|
|
@@ -141,6 +152,13 @@ class PetSettingUI(QWidget):
|
|
|
141
152
|
add_recent_file("pet", self.pet_image_path)
|
|
142
153
|
reload_recent_combobox(self.recent_files_combobox, "pet")
|
|
143
154
|
|
|
155
|
+
def choose_sound(self) -> None:
|
|
156
|
+
"""選擇點擊時播放的音效(選填)/ Choose an optional click sound."""
|
|
157
|
+
front_engine_logger.info("[PetSettingUI] choose_sound")
|
|
158
|
+
path = choose_wav_sound(self)
|
|
159
|
+
if path:
|
|
160
|
+
self.pet_sound_path = path
|
|
161
|
+
|
|
144
162
|
def choose_pack(self) -> None:
|
|
145
163
|
"""選擇動作包資料夾(依 walk/idle/climb/fall/drag 檔名對應狀態)。"""
|
|
146
164
|
front_engine_logger.info("[PetSettingUI] choose_pack")
|
|
@@ -188,6 +206,8 @@ class PetSettingUI(QWidget):
|
|
|
188
206
|
"behaviour": self.behaviour_combobox.currentData(),
|
|
189
207
|
"climb": self.climb_checkbox.isChecked(),
|
|
190
208
|
"talk": self.talk_checkbox.isChecked(),
|
|
209
|
+
"sound": self.pet_sound_path,
|
|
210
|
+
"sit": self.sit_checkbox.isChecked(),
|
|
191
211
|
}
|
|
192
212
|
|
|
193
213
|
def set_state(self, state: dict) -> None:
|
|
@@ -211,3 +231,7 @@ class PetSettingUI(QWidget):
|
|
|
211
231
|
self.climb_checkbox.setChecked(bool(state["climb"]))
|
|
212
232
|
if "talk" in state:
|
|
213
233
|
self.talk_checkbox.setChecked(bool(state["talk"]))
|
|
234
|
+
if state.get("sound"):
|
|
235
|
+
self.pet_sound_path = str(state["sound"])
|
|
236
|
+
if "sit" in state:
|
|
237
|
+
self.sit_checkbox.setChecked(bool(state["sit"]))
|
|
@@ -226,8 +226,10 @@ english_word_dict = {
|
|
|
226
226
|
"pet_climb_label": "Climb walls",
|
|
227
227
|
"pet_clone": "Clone",
|
|
228
228
|
"pet_choose_pack": "Choose pet pack...",
|
|
229
|
+
"pet_choose_sound": "Choose sound (optional)",
|
|
229
230
|
"pet_pack_empty": "No sprites (walk/idle/sleep/climb/fall/drag) found in that folder.",
|
|
230
231
|
"pet_talk_label": "Speech bubbles",
|
|
232
|
+
"pet_sit_label": "Sit on windows",
|
|
231
233
|
"pet_chatter_morning": "Good morning!|Rise and shine!|Ready for the day?",
|
|
232
234
|
"pet_chatter_afternoon": "Good afternoon!|Taking a break?|Keep it up!",
|
|
233
235
|
"pet_chatter_evening": "Good evening!|How was your day?|Almost done?",
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/multi_language/traditional_chinese.py
RENAMED
|
@@ -227,8 +227,10 @@ traditional_chinese_word_dict = {
|
|
|
227
227
|
"pet_climb_label": "攀爬牆壁",
|
|
228
228
|
"pet_clone": "複製",
|
|
229
229
|
"pet_choose_pack": "選擇動作包資料夾...",
|
|
230
|
+
"pet_choose_sound": "選擇音效(選填)",
|
|
230
231
|
"pet_pack_empty": "該資料夾找不到精靈檔(walk/idle/sleep/climb/fall/drag)。",
|
|
231
232
|
"pet_talk_label": "對話泡泡",
|
|
233
|
+
"pet_sit_label": "站在視窗上",
|
|
232
234
|
"pet_chatter_morning": "早安!|新的一天開始囉!|準備好了嗎?",
|
|
233
235
|
"pet_chatter_afternoon": "午安!|要不要休息一下?|繼續加油!",
|
|
234
236
|
"pet_chatter_evening": "晚上好!|今天過得如何?|快完成了嗎?",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frontengine
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.10
|
|
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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/control_center/control_center_ui.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/particle/particle_setting_ui.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/gif.py
RENAMED
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/image.py
RENAMED
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/registry.py
RENAMED
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/sound.py
RENAMED
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/text.py
RENAMED
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/video.py
RENAMED
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_page/web.py
RENAMED
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/scene_setting/scene_setting_ui.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/ui/page/sound_player/sound_player_setting_ui.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/critical_exit/check_key_is_press.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/multi_language/language_wrapper.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/multi_language/simplified_chinese.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/smart_pause/smart_pause_service.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.8 → frontengine-1.0.10}/frontengine/utils/theme_schedule/theme_schedule_service.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|