frontengine 1.0.9__tar.gz → 1.0.11__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.9 → frontengine-1.0.11}/PKG-INFO +1 -1
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/pet/desktop_pet.py +214 -29
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/pet/pet_setting_ui.py +20 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/multi_language/english.py +2 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/multi_language/traditional_chinese.py +2 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine.egg-info/PKG-INFO +1 -1
- {frontengine-1.0.9 → frontengine-1.0.11}/pyproject.toml +1 -1
- {frontengine-1.0.9 → frontengine-1.0.11}/LICENSE +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/README.md +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/__main__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/base_widget.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/gif/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/gif/paint_gif.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/image/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/image/paint_image.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/load/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/load/load_someone_make_ui.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/overlay_factory.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/particle/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/particle/particle_ui.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/pet/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/scene/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/scene/extend_graphic_scene.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/scene/extend_graphic_view.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/scene/scene.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/sound_player/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/sound_player/sound_effect.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/sound_player/sound_player.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/text/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/text/draw_text.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/video/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/video/video_player.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/web/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/web/webview.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/show/window_helpers.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/system_tray/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/system_tray/extend_system_tray.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/color/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/color/global_color.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/dialog/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/dialog/choose_file_dialog.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/dialog/hotkey_settings_dialog.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/dialog/save_file_dialog.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/main_ui.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/menu/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/menu/help_menu.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/menu/how_to_menu.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/menu/language_menu.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/menu/preset_menu.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/menu/settings_menu.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/control_center/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/control_center/control_center_ui.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/gif/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/gif/gif_setting_ui.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/image/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/image/image_setting_ui.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/particle/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/particle/particle_setting_ui.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/pet/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_manager.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/base_scene_page.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/gif.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/image.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/registry.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/sound.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/text.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/video.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/web.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_setting_ui.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/sound_player/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/sound_player/sound_player_setting_ui.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/text/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/text/text_setting_ui.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/utils.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/video/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/video/video_setting_ui.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/web/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/web/web_setting_ui.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/user_setting/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/user_setting/preset_repository.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/user_setting/scene_setting.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/user_setting/user_setting_file.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/browser/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/browser/browser.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/critical_exit/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/critical_exit/check_key_is_press.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/critical_exit/critical_exit.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/critical_exit/win32_vk.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/exception/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/exception/exception_tags.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/exception/exceptions.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/file/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/file/open/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/file/open/open_file.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/file/save/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/file/save/save_file.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/hotkey/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/hotkey/hotkey_service.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/json/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/json/json_file.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/json/json_repository.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/json_format/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/json_format/json_process.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/logging/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/logging/loggin_instance.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/multi_language/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/multi_language/france.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/multi_language/germany.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/multi_language/italy.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/multi_language/language_wrapper.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/multi_language/russian.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/multi_language/simplified_chinese.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/preset_schedule/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/preset_schedule/preset_schedule_service.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/redirect_manager/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/redirect_manager/redirect_manager_class.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/smart_pause/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/smart_pause/smart_pause_service.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/theme_schedule/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/theme_schedule/theme_schedule_service.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/web_url.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/worker/__init__.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine/worker/qthread_worker.py +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine.egg-info/SOURCES.txt +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine.egg-info/dependency_links.txt +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine.egg-info/entry_points.txt +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine.egg-info/requires.txt +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/frontengine.egg-info/top_level.txt +0 -0
- {frontengine-1.0.9 → frontengine-1.0.11}/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.11
|
|
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,4 +1,5 @@
|
|
|
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
|
|
@@ -96,6 +97,70 @@ def derive_visual_state(dragging: bool, airborne: bool, surface: str, motion_sta
|
|
|
96
97
|
return STATE_WALK
|
|
97
98
|
|
|
98
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
|
+
|
|
147
|
+
def nearest_peer(center, peers):
|
|
148
|
+
"""
|
|
149
|
+
回傳離 center 最近的同伴座標與距離;無同伴回傳 (None, inf)。
|
|
150
|
+
Return the nearest peer center and its distance to `center`, or
|
|
151
|
+
(None, inf) when there are no peers.
|
|
152
|
+
"""
|
|
153
|
+
best = None
|
|
154
|
+
best_distance = float("inf")
|
|
155
|
+
cx, cy = center
|
|
156
|
+
for peer_x, peer_y in peers:
|
|
157
|
+
distance = ((peer_x - cx) ** 2 + (peer_y - cy) ** 2) ** 0.5
|
|
158
|
+
if distance < best_distance:
|
|
159
|
+
best_distance = distance
|
|
160
|
+
best = (peer_x, peer_y)
|
|
161
|
+
return best, best_distance
|
|
162
|
+
|
|
163
|
+
|
|
99
164
|
def message_bucket(hour: int) -> str:
|
|
100
165
|
"""依小時回傳時段 / Time-of-day bucket for the given hour."""
|
|
101
166
|
hour = int(hour) % 24
|
|
@@ -252,6 +317,12 @@ class PetMotion:
|
|
|
252
317
|
self.asleep = False
|
|
253
318
|
self.climb = bool(climb)
|
|
254
319
|
self.surface = SURFACE_FLOOR
|
|
320
|
+
# 可站立的視窗平台 (left, right, top_y);站在平台上時的狀態
|
|
321
|
+
# Standable window platforms (left, right, top_y) and platform state.
|
|
322
|
+
self.platforms: list = []
|
|
323
|
+
self.on_platform = False
|
|
324
|
+
self.platform_span: Optional[Tuple[float, float]] = None
|
|
325
|
+
self.ground_feet = 0.0
|
|
255
326
|
|
|
256
327
|
@property
|
|
257
328
|
def facing_left(self) -> bool:
|
|
@@ -260,6 +331,10 @@ class PetMotion:
|
|
|
260
331
|
def set_bounds(self, bounds: Tuple[int, int, int, int]) -> None:
|
|
261
332
|
self.bounds = bounds
|
|
262
333
|
|
|
334
|
+
def set_platforms(self, platforms) -> None:
|
|
335
|
+
"""設定可站立的視窗上緣平台 / Set standable window top-edge platforms."""
|
|
336
|
+
self.platforms = list(platforms)
|
|
337
|
+
|
|
263
338
|
def set_target(self, x: float, y: float) -> None:
|
|
264
339
|
self.target = (float(x), float(y))
|
|
265
340
|
|
|
@@ -270,6 +345,8 @@ class PetMotion:
|
|
|
270
345
|
self._airborne = True
|
|
271
346
|
self.asleep = False
|
|
272
347
|
self.surface = SURFACE_FLOOR
|
|
348
|
+
self.on_platform = False
|
|
349
|
+
self.platform_span = None
|
|
273
350
|
|
|
274
351
|
def step(self) -> Tuple[int, int]:
|
|
275
352
|
left, top, right, bottom = self.bounds
|
|
@@ -280,38 +357,19 @@ class PetMotion:
|
|
|
280
357
|
return self._step_wander(left, top, right, bottom)
|
|
281
358
|
return self._step_floor(left, top, right, bottom, floor_y)
|
|
282
359
|
|
|
283
|
-
# --- floor / gravity / climbing ---
|
|
360
|
+
# --- floor / gravity / climbing / window platforms ---
|
|
284
361
|
def _step_floor(self, left, top, right, bottom, floor_y) -> Tuple[int, int]:
|
|
285
|
-
airborne = self._airborne or (
|
|
362
|
+
airborne = self._airborne or (
|
|
363
|
+
not self.on_platform and self.surface == SURFACE_FLOOR and self.y < floor_y - 0.5
|
|
364
|
+
)
|
|
286
365
|
if airborne:
|
|
287
|
-
self.
|
|
288
|
-
|
|
289
|
-
self.
|
|
290
|
-
if self.x <= left:
|
|
291
|
-
self.x = float(left)
|
|
292
|
-
self.vx = abs(self.vx) * self.WALL_DAMPING
|
|
293
|
-
elif self.x + self.width >= right:
|
|
294
|
-
self.x = float(right - self.width)
|
|
295
|
-
self.vx = -abs(self.vx) * self.WALL_DAMPING
|
|
296
|
-
if self.y <= top:
|
|
297
|
-
self.y = float(top)
|
|
298
|
-
self.vy = abs(self.vy) * self.WALL_DAMPING
|
|
299
|
-
if self.y >= floor_y:
|
|
300
|
-
self.y = float(floor_y)
|
|
301
|
-
if abs(self.vy) > self.BOUNCE_THRESHOLD:
|
|
302
|
-
self.vy = -self.vy * self.BOUNCE_DAMPING
|
|
303
|
-
else:
|
|
304
|
-
self.vy = 0.0
|
|
305
|
-
self._airborne = False
|
|
306
|
-
self.surface = SURFACE_FLOOR
|
|
307
|
-
self.vx = float(self.speed) if self.vx >= 0 else float(-self.speed)
|
|
308
|
-
self._new_state(force_walk=True)
|
|
309
|
-
return int(self.x), int(self.y)
|
|
310
|
-
|
|
366
|
+
return self._step_fall(left, top, right, bottom, floor_y)
|
|
367
|
+
if self.on_platform:
|
|
368
|
+
return self._step_platform(left, top, right, bottom, floor_y)
|
|
311
369
|
if self.surface != SURFACE_FLOOR:
|
|
312
370
|
return self._step_climb(left, top, right, bottom, floor_y)
|
|
313
371
|
|
|
314
|
-
# grounded on the floor: random walk / idle, with a chance to climb a wall
|
|
372
|
+
# grounded on the screen floor: random walk / idle, with a chance to climb a wall
|
|
315
373
|
self.y = float(floor_y)
|
|
316
374
|
if self._state_ticks <= 0:
|
|
317
375
|
self._new_state()
|
|
@@ -335,6 +393,84 @@ class PetMotion:
|
|
|
335
393
|
self.vx = -abs(self.vx)
|
|
336
394
|
return int(self.x), int(self.y)
|
|
337
395
|
|
|
396
|
+
def _step_fall(self, left, top, right, bottom, floor_y) -> Tuple[int, int]:
|
|
397
|
+
"""落下:撞牆/天花板反彈,並在越過視窗平台或螢幕地板時落地。"""
|
|
398
|
+
prev_feet = self.y + self.height
|
|
399
|
+
self.vy += self.GRAVITY
|
|
400
|
+
self.x += self.vx
|
|
401
|
+
self.y += self.vy
|
|
402
|
+
if self.x <= left:
|
|
403
|
+
self.x = float(left)
|
|
404
|
+
self.vx = abs(self.vx) * self.WALL_DAMPING
|
|
405
|
+
elif self.x + self.width >= right:
|
|
406
|
+
self.x = float(right - self.width)
|
|
407
|
+
self.vx = -abs(self.vx) * self.WALL_DAMPING
|
|
408
|
+
if self.y <= top:
|
|
409
|
+
self.y = float(top)
|
|
410
|
+
self.vy = abs(self.vy) * self.WALL_DAMPING
|
|
411
|
+
new_feet = self.y + self.height
|
|
412
|
+
center_x = self.x + self.width / 2.0
|
|
413
|
+
|
|
414
|
+
land_feet = None
|
|
415
|
+
land_span = None
|
|
416
|
+
for platform_left, platform_right, platform_y in self.platforms:
|
|
417
|
+
if platform_left <= center_x <= platform_right and prev_feet <= platform_y <= new_feet:
|
|
418
|
+
if land_feet is None or platform_y < land_feet:
|
|
419
|
+
land_feet = float(platform_y)
|
|
420
|
+
land_span = (float(platform_left), float(platform_right))
|
|
421
|
+
if prev_feet <= bottom <= new_feet and (land_feet is None or bottom < land_feet):
|
|
422
|
+
land_feet = float(bottom)
|
|
423
|
+
land_span = None
|
|
424
|
+
|
|
425
|
+
if land_feet is not None:
|
|
426
|
+
self.y = float(land_feet - self.height)
|
|
427
|
+
if abs(self.vy) > self.BOUNCE_THRESHOLD:
|
|
428
|
+
self.vy = -self.vy * self.BOUNCE_DAMPING
|
|
429
|
+
else:
|
|
430
|
+
self.vy = 0.0
|
|
431
|
+
self._airborne = False
|
|
432
|
+
self.surface = SURFACE_FLOOR
|
|
433
|
+
self.on_platform = land_span is not None
|
|
434
|
+
self.platform_span = land_span
|
|
435
|
+
self.ground_feet = land_feet
|
|
436
|
+
self.vx = float(self.speed) if self.vx >= 0 else float(-self.speed)
|
|
437
|
+
self._new_state(force_walk=True)
|
|
438
|
+
return int(self.x), int(self.y)
|
|
439
|
+
|
|
440
|
+
def _platform_under(self) -> Optional[Tuple[float, float]]:
|
|
441
|
+
"""回傳目前站立平台的水平範圍;平台已消失(視窗移走/關閉)則回傳 None。"""
|
|
442
|
+
body_left = self.x
|
|
443
|
+
body_right = self.x + self.width
|
|
444
|
+
for platform_left, platform_right, platform_y in self.platforms:
|
|
445
|
+
if abs(platform_y - self.ground_feet) <= 2.0 and not (platform_right < body_left or platform_left > body_right):
|
|
446
|
+
return (float(platform_left), float(platform_right))
|
|
447
|
+
return None
|
|
448
|
+
|
|
449
|
+
def _step_platform(self, left, top, right, bottom, floor_y) -> Tuple[int, int]:
|
|
450
|
+
"""站在視窗平台上走動;到平台兩端轉向;平台消失則掉落。"""
|
|
451
|
+
span = self._platform_under()
|
|
452
|
+
if span is None:
|
|
453
|
+
self._airborne = True
|
|
454
|
+
self.on_platform = False
|
|
455
|
+
self.platform_span = None
|
|
456
|
+
return self._step_fall(left, top, right, bottom, floor_y)
|
|
457
|
+
self.platform_span = span
|
|
458
|
+
span_left, span_right = span
|
|
459
|
+
self.y = float(self.ground_feet - self.height)
|
|
460
|
+
if self._state_ticks <= 0:
|
|
461
|
+
self._new_state()
|
|
462
|
+
self._state_ticks -= 1
|
|
463
|
+
if self.state != "walk":
|
|
464
|
+
return int(self.x), int(self.y)
|
|
465
|
+
self.x += self.vx
|
|
466
|
+
if self.x <= span_left:
|
|
467
|
+
self.x = float(span_left)
|
|
468
|
+
self.vx = abs(self.vx)
|
|
469
|
+
elif self.x + self.width >= span_right:
|
|
470
|
+
self.x = float(span_right - self.width)
|
|
471
|
+
self.vx = -abs(self.vx)
|
|
472
|
+
return int(self.x), int(self.y)
|
|
473
|
+
|
|
338
474
|
def _step_climb(self, left, top, right, bottom, floor_y) -> Tuple[int, int]:
|
|
339
475
|
"""沿螢幕邊緣爬行;隨機放手則掉落 / Crawl the screen perimeter; may let go and fall."""
|
|
340
476
|
if self._rng.random() < self.DROP_CHANCE:
|
|
@@ -453,10 +589,11 @@ class DesktopPetWidget(BaseWidget):
|
|
|
453
589
|
|
|
454
590
|
def __init__(self, image_path: str, size: int = 128, speed: int = 3,
|
|
455
591
|
behaviour: str = BEHAVIOUR_FLOOR, climb: bool = True, talk: bool = True,
|
|
456
|
-
sound_path: Optional[str] = None):
|
|
592
|
+
sound_path: Optional[str] = None, sit_on_windows: bool = True):
|
|
457
593
|
front_engine_logger.info(
|
|
458
594
|
f"[DesktopPetWidget] Init | path={image_path}, size={size}, speed={speed}, "
|
|
459
|
-
f"behaviour={behaviour}, climb={climb}, talk={talk}, sound={sound_path}"
|
|
595
|
+
f"behaviour={behaviour}, climb={climb}, talk={talk}, sound={sound_path}, "
|
|
596
|
+
f"sit_on_windows={sit_on_windows}"
|
|
460
597
|
)
|
|
461
598
|
super().__init__()
|
|
462
599
|
self.opacity = 1.0
|
|
@@ -494,6 +631,12 @@ class DesktopPetWidget(BaseWidget):
|
|
|
494
631
|
self._messages = self._load_messages()
|
|
495
632
|
self._sound: Optional[QSoundEffect] = None
|
|
496
633
|
self._init_sound(sound_path)
|
|
634
|
+
self._sit_on_windows = bool(sit_on_windows)
|
|
635
|
+
self._platform_tick = 0
|
|
636
|
+
# 多寵物互動 / Multi-pet interaction
|
|
637
|
+
self._peers_provider = None
|
|
638
|
+
self._peer_greeted = False
|
|
639
|
+
self._peer_tick = 0
|
|
497
640
|
self._bubble = SpeechBubble()
|
|
498
641
|
self._chatter_timer = QTimer(self)
|
|
499
642
|
self._chatter_timer.setSingleShot(True)
|
|
@@ -507,10 +650,42 @@ class DesktopPetWidget(BaseWidget):
|
|
|
507
650
|
self.close_action.triggered.connect(self.close)
|
|
508
651
|
self.menu.addAction(self.close_action)
|
|
509
652
|
|
|
653
|
+
MEET_DISTANCE = 90.0
|
|
654
|
+
|
|
510
655
|
def set_pet_window_flag(self) -> None:
|
|
511
656
|
"""寵物需接收滑鼠以便拖曳,故 allow_input=True 並置頂。"""
|
|
512
657
|
apply_overlay_window_flags(self, show_on_bottom=False, allow_input=True)
|
|
513
658
|
|
|
659
|
+
def center(self) -> Tuple[int, int]:
|
|
660
|
+
return (self.x() + self.width() // 2, self.y() + self.height() // 2)
|
|
661
|
+
|
|
662
|
+
def set_peers_provider(self, provider) -> None:
|
|
663
|
+
"""設定回傳其他寵物中心座標清單的函式 / Provider of other pets' centres."""
|
|
664
|
+
self._peers_provider = provider
|
|
665
|
+
|
|
666
|
+
def _check_peers(self) -> None:
|
|
667
|
+
"""靠近其他寵物時轉向並打招呼(帶遲滯,避免重複)。"""
|
|
668
|
+
if self._peers_provider is None or not self._talk:
|
|
669
|
+
return
|
|
670
|
+
try:
|
|
671
|
+
peers = self._peers_provider()
|
|
672
|
+
except Exception: # pragma: no cover - defensive
|
|
673
|
+
return
|
|
674
|
+
my_center = self.center()
|
|
675
|
+
peer, distance = nearest_peer(my_center, peers)
|
|
676
|
+
if peer is None:
|
|
677
|
+
self._peer_greeted = False
|
|
678
|
+
return
|
|
679
|
+
if distance <= self.MEET_DISTANCE:
|
|
680
|
+
if not self._peer_greeted:
|
|
681
|
+
self._peer_greeted = True
|
|
682
|
+
self.motion.vx = abs(self.motion.vx) if peer[0] >= my_center[0] else -abs(self.motion.vx)
|
|
683
|
+
pool = self._messages.get("meet") or []
|
|
684
|
+
if pool:
|
|
685
|
+
self.say(pool[self._chatter_rng.randrange(len(pool))])
|
|
686
|
+
elif distance > self.MEET_DISTANCE * 1.6:
|
|
687
|
+
self._peer_greeted = False
|
|
688
|
+
|
|
514
689
|
def _load_sprite(self, path: str):
|
|
515
690
|
if Path(path).suffix.lower() in (".gif", ".webp"):
|
|
516
691
|
movie = QMovie(str(path))
|
|
@@ -590,6 +765,7 @@ class DesktopPetWidget(BaseWidget):
|
|
|
590
765
|
"night": lines("pet_chatter_night", "It's late - get some rest!|Still up?"),
|
|
591
766
|
"happy": lines("pet_chatter_happy", "I'm so happy!|You're the best!|(^o^)"),
|
|
592
767
|
"sad": lines("pet_chatter_sad", "Feeling a bit lonely...|Pet me?|(._.)"),
|
|
768
|
+
"meet": lines("pet_chatter_meet", "Hi friend!|Hello!|Let's play!"),
|
|
593
769
|
"any": lines("pet_chatter_any", "Hi there!|(^_^)|Keep going!"),
|
|
594
770
|
}
|
|
595
771
|
|
|
@@ -645,9 +821,18 @@ class DesktopPetWidget(BaseWidget):
|
|
|
645
821
|
if self.motion.behaviour == BEHAVIOUR_CHASE:
|
|
646
822
|
cursor = QCursor.pos()
|
|
647
823
|
self.motion.set_target(cursor.x(), cursor.y())
|
|
824
|
+
elif self._sit_on_windows and self.motion.behaviour == BEHAVIOUR_FLOOR:
|
|
825
|
+
self._platform_tick += 1
|
|
826
|
+
if self._platform_tick >= 10:
|
|
827
|
+
self._platform_tick = 0
|
|
828
|
+
self.motion.set_platforms(windows_platforms(exclude_hwnds=(int(self.winId()),)))
|
|
648
829
|
x, y = self.motion.step()
|
|
649
830
|
self.move(x, y)
|
|
650
831
|
self._set_active_sprite(self._visual_state())
|
|
832
|
+
self._peer_tick += 1
|
|
833
|
+
if self._peer_tick >= 5:
|
|
834
|
+
self._peer_tick = 0
|
|
835
|
+
self._check_peers()
|
|
651
836
|
if self._bubble.isVisible():
|
|
652
837
|
self._bubble.reposition(self)
|
|
653
838
|
|
|
@@ -76,6 +76,8 @@ class PetSettingUI(QWidget):
|
|
|
76
76
|
self.climb_checkbox.setChecked(True)
|
|
77
77
|
self.talk_checkbox = QCheckBox(language_wrapper.language_word_dict.get("pet_talk_label", "Speech bubbles"))
|
|
78
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)
|
|
79
81
|
|
|
80
82
|
# Start
|
|
81
83
|
self.start_button = QPushButton(language_wrapper.language_word_dict.get("pet_start", "Spawn pet"))
|
|
@@ -102,6 +104,7 @@ class PetSettingUI(QWidget):
|
|
|
102
104
|
self.grid_layout.addWidget(self.behaviour_combobox, 3, 1)
|
|
103
105
|
self.grid_layout.addWidget(self.climb_checkbox, 3, 2)
|
|
104
106
|
self.grid_layout.addWidget(self.talk_checkbox, 2, 2)
|
|
107
|
+
self.grid_layout.addWidget(self.sit_checkbox, 4, 2)
|
|
105
108
|
self.grid_layout.addWidget(self.start_button, 4, 0)
|
|
106
109
|
self.grid_layout.addWidget(self.recent_files_label, 5, 0)
|
|
107
110
|
self.grid_layout.addWidget(self.recent_files_combobox, 5, 1)
|
|
@@ -118,8 +121,10 @@ class PetSettingUI(QWidget):
|
|
|
118
121
|
climb=self.climb_checkbox.isChecked(),
|
|
119
122
|
talk=self.talk_checkbox.isChecked(),
|
|
120
123
|
sound_path=self.pet_sound_path,
|
|
124
|
+
sit_on_windows=self.sit_checkbox.isChecked(),
|
|
121
125
|
)
|
|
122
126
|
pet.clone_requested.connect(self._spawn_pet)
|
|
127
|
+
pet.set_peers_provider(lambda me=pet: self._peer_centers(me))
|
|
123
128
|
pet.set_pet_window_flag()
|
|
124
129
|
self.pet_list.append(pet)
|
|
125
130
|
screen = QGuiApplication.primaryScreen()
|
|
@@ -128,6 +133,18 @@ class PetSettingUI(QWidget):
|
|
|
128
133
|
if geometry is not None:
|
|
129
134
|
pet.start_moving((geometry.left(), geometry.top(), geometry.right(), geometry.bottom()))
|
|
130
135
|
|
|
136
|
+
def _peer_centers(self, me) -> list:
|
|
137
|
+
"""回傳其他仍存活寵物的中心座標(略過已被銷毀者)。"""
|
|
138
|
+
centers = []
|
|
139
|
+
for other in list(self.pet_list):
|
|
140
|
+
if other is me:
|
|
141
|
+
continue
|
|
142
|
+
try:
|
|
143
|
+
centers.append(other.center())
|
|
144
|
+
except RuntimeError:
|
|
145
|
+
pass # underlying C++ object already deleted
|
|
146
|
+
return centers
|
|
147
|
+
|
|
131
148
|
def start_play_pet(self) -> None:
|
|
132
149
|
front_engine_logger.info("[PetSettingUI] start_play_pet")
|
|
133
150
|
if not self.pet_image_path or not self.ready_to_play:
|
|
@@ -203,6 +220,7 @@ class PetSettingUI(QWidget):
|
|
|
203
220
|
"climb": self.climb_checkbox.isChecked(),
|
|
204
221
|
"talk": self.talk_checkbox.isChecked(),
|
|
205
222
|
"sound": self.pet_sound_path,
|
|
223
|
+
"sit": self.sit_checkbox.isChecked(),
|
|
206
224
|
}
|
|
207
225
|
|
|
208
226
|
def set_state(self, state: dict) -> None:
|
|
@@ -228,3 +246,5 @@ class PetSettingUI(QWidget):
|
|
|
228
246
|
self.talk_checkbox.setChecked(bool(state["talk"]))
|
|
229
247
|
if state.get("sound"):
|
|
230
248
|
self.pet_sound_path = str(state["sound"])
|
|
249
|
+
if "sit" in state:
|
|
250
|
+
self.sit_checkbox.setChecked(bool(state["sit"]))
|
|
@@ -229,6 +229,7 @@ english_word_dict = {
|
|
|
229
229
|
"pet_choose_sound": "Choose sound (optional)",
|
|
230
230
|
"pet_pack_empty": "No sprites (walk/idle/sleep/climb/fall/drag) found in that folder.",
|
|
231
231
|
"pet_talk_label": "Speech bubbles",
|
|
232
|
+
"pet_sit_label": "Sit on windows",
|
|
232
233
|
"pet_chatter_morning": "Good morning!|Rise and shine!|Ready for the day?",
|
|
233
234
|
"pet_chatter_afternoon": "Good afternoon!|Taking a break?|Keep it up!",
|
|
234
235
|
"pet_chatter_evening": "Good evening!|How was your day?|Almost done?",
|
|
@@ -236,6 +237,7 @@ english_word_dict = {
|
|
|
236
237
|
"pet_chatter_any": "Hi there!|(^_^)|Keep going!|You've got this!",
|
|
237
238
|
"pet_chatter_happy": "I'm so happy!|You're the best!|(^o^)/|Best day ever!",
|
|
238
239
|
"pet_chatter_sad": "Feeling a bit lonely...|Pet me?|(._.)|Don't forget about me~",
|
|
240
|
+
"pet_chatter_meet": "Hi friend!|Hello there!|Let's play!|Fancy meeting you here!",
|
|
239
241
|
"pet_start": "Spawn pet",
|
|
240
242
|
"pet_message_box_text": "Pet image not found",
|
|
241
243
|
}
|
{frontengine-1.0.9 → frontengine-1.0.11}/frontengine/utils/multi_language/traditional_chinese.py
RENAMED
|
@@ -230,6 +230,7 @@ traditional_chinese_word_dict = {
|
|
|
230
230
|
"pet_choose_sound": "選擇音效(選填)",
|
|
231
231
|
"pet_pack_empty": "該資料夾找不到精靈檔(walk/idle/sleep/climb/fall/drag)。",
|
|
232
232
|
"pet_talk_label": "對話泡泡",
|
|
233
|
+
"pet_sit_label": "站在視窗上",
|
|
233
234
|
"pet_chatter_morning": "早安!|新的一天開始囉!|準備好了嗎?",
|
|
234
235
|
"pet_chatter_afternoon": "午安!|要不要休息一下?|繼續加油!",
|
|
235
236
|
"pet_chatter_evening": "晚上好!|今天過得如何?|快完成了嗎?",
|
|
@@ -237,6 +238,7 @@ traditional_chinese_word_dict = {
|
|
|
237
238
|
"pet_chatter_any": "嗨!|(^_^)|加油!|你可以的!",
|
|
238
239
|
"pet_chatter_happy": "我好開心!|你最棒了!|(^o^)/|今天真美好!",
|
|
239
240
|
"pet_chatter_sad": "有點寂寞…|摸摸我好嗎?|(._.)|別忘了我~",
|
|
241
|
+
"pet_chatter_meet": "嗨朋友!|你好呀!|一起玩吧!|在這遇到你真巧!",
|
|
240
242
|
"pet_start": "召喚寵物",
|
|
241
243
|
"pet_message_box_text": "找不到寵物圖片",
|
|
242
244
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frontengine
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.11
|
|
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.9 → frontengine-1.0.11}/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.9 → frontengine-1.0.11}/frontengine/ui/page/particle/particle_setting_ui.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/gif.py
RENAMED
|
File without changes
|
{frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/image.py
RENAMED
|
File without changes
|
{frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/registry.py
RENAMED
|
File without changes
|
{frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/sound.py
RENAMED
|
File without changes
|
{frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/text.py
RENAMED
|
File without changes
|
{frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/video.py
RENAMED
|
File without changes
|
{frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_page/web.py
RENAMED
|
File without changes
|
{frontengine-1.0.9 → frontengine-1.0.11}/frontengine/ui/page/scene_setting/scene_setting_ui.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.9 → frontengine-1.0.11}/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.9 → frontengine-1.0.11}/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.9 → frontengine-1.0.11}/frontengine/utils/multi_language/language_wrapper.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.9 → frontengine-1.0.11}/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.9 → frontengine-1.0.11}/frontengine/utils/smart_pause/smart_pause_service.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.9 → frontengine-1.0.11}/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
|