frontengine 1.0.4__tar.gz → 1.0.6__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.4 → frontengine-1.0.6}/PKG-INFO +1 -1
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/pet/desktop_pet.py +246 -24
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/pet/pet_setting_ui.py +36 -2
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/multi_language/english.py +8 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/multi_language/traditional_chinese.py +8 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine.egg-info/PKG-INFO +1 -1
- {frontengine-1.0.4 → frontengine-1.0.6}/pyproject.toml +1 -1
- {frontengine-1.0.4 → frontengine-1.0.6}/LICENSE +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/README.md +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/__main__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/base_widget.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/gif/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/gif/paint_gif.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/image/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/image/paint_image.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/load/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/load/load_someone_make_ui.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/overlay_factory.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/particle/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/particle/particle_ui.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/pet/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/scene/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/scene/extend_graphic_scene.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/scene/extend_graphic_view.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/scene/scene.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/sound_player/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/sound_player/sound_effect.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/sound_player/sound_player.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/text/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/text/draw_text.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/video/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/video/video_player.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/web/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/web/webview.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/show/window_helpers.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/system_tray/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/system_tray/extend_system_tray.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/color/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/color/global_color.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/dialog/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/dialog/choose_file_dialog.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/dialog/hotkey_settings_dialog.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/dialog/save_file_dialog.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/main_ui.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/menu/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/menu/help_menu.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/menu/how_to_menu.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/menu/language_menu.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/menu/preset_menu.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/menu/settings_menu.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/control_center/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/control_center/control_center_ui.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/gif/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/gif/gif_setting_ui.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/image/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/image/image_setting_ui.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/particle/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/particle/particle_setting_ui.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/pet/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_manager.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/base_scene_page.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/gif.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/image.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/registry.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/sound.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/text.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/video.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/web.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_setting_ui.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/sound_player/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/sound_player/sound_player_setting_ui.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/text/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/text/text_setting_ui.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/utils.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/video/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/video/video_setting_ui.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/web/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/web/web_setting_ui.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/user_setting/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/user_setting/preset_repository.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/user_setting/scene_setting.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/user_setting/user_setting_file.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/browser/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/browser/browser.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/critical_exit/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/critical_exit/check_key_is_press.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/critical_exit/critical_exit.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/critical_exit/win32_vk.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/exception/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/exception/exception_tags.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/exception/exceptions.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/file/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/file/open/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/file/open/open_file.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/file/save/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/file/save/save_file.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/hotkey/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/hotkey/hotkey_service.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/json/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/json/json_file.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/json/json_repository.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/json_format/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/json_format/json_process.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/logging/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/logging/loggin_instance.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/multi_language/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/multi_language/france.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/multi_language/germany.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/multi_language/italy.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/multi_language/language_wrapper.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/multi_language/russian.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/multi_language/simplified_chinese.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/preset_schedule/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/preset_schedule/preset_schedule_service.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/redirect_manager/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/redirect_manager/redirect_manager_class.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/smart_pause/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/smart_pause/smart_pause_service.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/theme_schedule/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/theme_schedule/theme_schedule_service.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/web_url.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/worker/__init__.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine/worker/qthread_worker.py +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine.egg-info/SOURCES.txt +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine.egg-info/dependency_links.txt +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine.egg-info/entry_points.txt +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine.egg-info/requires.txt +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/frontengine.egg-info/top_level.txt +0 -0
- {frontengine-1.0.4 → frontengine-1.0.6}/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.6
|
|
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,11 @@
|
|
|
1
1
|
import random as _random_module
|
|
2
|
+
from datetime import datetime
|
|
2
3
|
from pathlib import Path
|
|
3
4
|
from typing import Optional, Tuple
|
|
4
5
|
|
|
5
6
|
from PySide6.QtCore import Qt, QRect, QTimer, Signal
|
|
6
|
-
from PySide6.QtGui import QAction, QCursor, QMovie, QPainter, QPixmap, QTransform
|
|
7
|
-
from PySide6.QtWidgets import QMenu, QMessageBox
|
|
7
|
+
from PySide6.QtGui import QAction, QColor, QCursor, QFont, QFontMetrics, QMovie, QPainter, QPixmap, QTransform
|
|
8
|
+
from PySide6.QtWidgets import QMenu, QMessageBox, QWidget
|
|
8
9
|
|
|
9
10
|
from frontengine.show.base_widget import BaseWidget
|
|
10
11
|
from frontengine.show.window_helpers import apply_overlay_window_flags
|
|
@@ -22,6 +23,131 @@ SURFACE_LEFT = "left"
|
|
|
22
23
|
SURFACE_CEILING = "ceiling"
|
|
23
24
|
SURFACE_RIGHT = "right"
|
|
24
25
|
|
|
26
|
+
# 視覺狀態(決定顯示哪張精靈)/ Visual states (which sprite to show)
|
|
27
|
+
STATE_WALK = "walk"
|
|
28
|
+
STATE_IDLE = "idle"
|
|
29
|
+
STATE_CLIMB = "climb"
|
|
30
|
+
STATE_FALL = "fall"
|
|
31
|
+
STATE_DRAG = "drag"
|
|
32
|
+
|
|
33
|
+
# 動作包(資料夾)中,各狀態可接受的檔名(不含副檔名,先命中者為準)
|
|
34
|
+
# Accepted file stems per state inside a pet pack folder (first match wins).
|
|
35
|
+
_PACK_STATE_ALIASES = {
|
|
36
|
+
STATE_WALK: ("walk", "run", "move"),
|
|
37
|
+
STATE_IDLE: ("idle", "sit", "stand", "sleep"),
|
|
38
|
+
STATE_CLIMB: ("climb", "grab", "wall"),
|
|
39
|
+
STATE_FALL: ("fall", "jump"),
|
|
40
|
+
STATE_DRAG: ("drag", "pinch", "grabbed", "held"),
|
|
41
|
+
}
|
|
42
|
+
_PACK_EXTS = (".gif", ".webp", ".png", ".jpg", ".jpeg")
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def scan_pet_pack(folder: str) -> dict:
|
|
46
|
+
"""
|
|
47
|
+
掃描動作包資料夾,回傳「視覺狀態 -> 圖片路徑」對應。非資料夾回傳空 dict。
|
|
48
|
+
Scan a pet-pack folder and return a ``state -> image path`` mapping.
|
|
49
|
+
Returns {} when `folder` is not a directory.
|
|
50
|
+
"""
|
|
51
|
+
result: dict = {}
|
|
52
|
+
try:
|
|
53
|
+
folder_path = Path(folder)
|
|
54
|
+
if not folder_path.is_dir():
|
|
55
|
+
return result
|
|
56
|
+
by_stem = {
|
|
57
|
+
path.stem.lower(): path
|
|
58
|
+
for path in sorted(folder_path.iterdir())
|
|
59
|
+
if path.is_file() and path.suffix.lower() in _PACK_EXTS
|
|
60
|
+
}
|
|
61
|
+
for state, aliases in _PACK_STATE_ALIASES.items():
|
|
62
|
+
for alias in aliases:
|
|
63
|
+
if alias in by_stem:
|
|
64
|
+
result[state] = str(by_stem[alias])
|
|
65
|
+
break
|
|
66
|
+
except OSError:
|
|
67
|
+
pass
|
|
68
|
+
return result
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def derive_visual_state(dragging: bool, airborne: bool, surface: str, motion_state: str) -> str:
|
|
72
|
+
"""依目前情形推導應顯示的視覺狀態 / Derive which sprite state to show."""
|
|
73
|
+
if dragging:
|
|
74
|
+
return STATE_DRAG
|
|
75
|
+
if airborne:
|
|
76
|
+
return STATE_FALL
|
|
77
|
+
if surface in (SURFACE_LEFT, SURFACE_RIGHT, SURFACE_CEILING):
|
|
78
|
+
return STATE_CLIMB
|
|
79
|
+
if surface == SURFACE_FLOOR and motion_state == "idle":
|
|
80
|
+
return STATE_IDLE
|
|
81
|
+
return STATE_WALK
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
def message_bucket(hour: int) -> str:
|
|
85
|
+
"""依小時回傳時段 / Time-of-day bucket for the given hour."""
|
|
86
|
+
hour = int(hour) % 24
|
|
87
|
+
if 5 <= hour < 12:
|
|
88
|
+
return "morning"
|
|
89
|
+
if 12 <= hour < 18:
|
|
90
|
+
return "afternoon"
|
|
91
|
+
if 18 <= hour < 22:
|
|
92
|
+
return "evening"
|
|
93
|
+
return "night"
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
def pick_message(hour: int, rng, messages: dict) -> str:
|
|
97
|
+
"""
|
|
98
|
+
依時段從對應句庫(加上通用句庫)隨機挑一句台詞;句庫皆空回傳空字串。
|
|
99
|
+
Pick a chatter line from the time bucket plus the generic pool. rng needs
|
|
100
|
+
a ``randrange`` method (injectable for tests).
|
|
101
|
+
"""
|
|
102
|
+
pool = list(messages.get(message_bucket(hour), [])) + list(messages.get("any", []))
|
|
103
|
+
if not pool:
|
|
104
|
+
return ""
|
|
105
|
+
return pool[rng.randrange(len(pool))]
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class SpeechBubble(QWidget):
|
|
109
|
+
"""寵物頭上的小對話泡泡,數秒後自動消失 / A small speech bubble that auto-hides."""
|
|
110
|
+
|
|
111
|
+
def __init__(self) -> None:
|
|
112
|
+
super().__init__()
|
|
113
|
+
self._text = ""
|
|
114
|
+
self._font = QFont()
|
|
115
|
+
self._font.setPointSize(11)
|
|
116
|
+
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
|
|
117
|
+
apply_overlay_window_flags(self, show_on_bottom=False, allow_input=False)
|
|
118
|
+
self._hide_timer = QTimer(self)
|
|
119
|
+
self._hide_timer.setSingleShot(True)
|
|
120
|
+
self._hide_timer.timeout.connect(self.hide)
|
|
121
|
+
|
|
122
|
+
def show_message(self, text: str, anchor: QWidget, duration_ms: int = 4000) -> None:
|
|
123
|
+
self._text = text
|
|
124
|
+
width = min(260, QFontMetrics(self._font).horizontalAdvance(text) + 28)
|
|
125
|
+
self.resize(max(60, width), 44)
|
|
126
|
+
self.reposition(anchor)
|
|
127
|
+
self.show()
|
|
128
|
+
self.raise_()
|
|
129
|
+
self.update()
|
|
130
|
+
self._hide_timer.start(max(500, int(duration_ms)))
|
|
131
|
+
|
|
132
|
+
def reposition(self, anchor: QWidget) -> None:
|
|
133
|
+
geo = anchor.frameGeometry()
|
|
134
|
+
self.move(geo.center().x() - self.width() // 2, geo.top() - self.height() - 6)
|
|
135
|
+
|
|
136
|
+
def paintEvent(self, event) -> None:
|
|
137
|
+
painter = QPainter(self)
|
|
138
|
+
painter.setRenderHint(QPainter.RenderHint.Antialiasing)
|
|
139
|
+
rect = self.rect().adjusted(1, 1, -1, -1)
|
|
140
|
+
painter.setBrush(QColor(255, 255, 240, 235))
|
|
141
|
+
painter.setPen(QColor(90, 90, 90))
|
|
142
|
+
painter.drawRoundedRect(rect, 8, 8)
|
|
143
|
+
painter.setPen(QColor(30, 30, 30))
|
|
144
|
+
painter.setFont(self._font)
|
|
145
|
+
painter.drawText(
|
|
146
|
+
rect.adjusted(8, 2, -8, -2),
|
|
147
|
+
int(Qt.AlignmentFlag.AlignCenter | Qt.TextFlag.TextWordWrap),
|
|
148
|
+
self._text,
|
|
149
|
+
)
|
|
150
|
+
|
|
25
151
|
|
|
26
152
|
class PetMotion:
|
|
27
153
|
"""
|
|
@@ -260,30 +386,26 @@ class DesktopPetWidget(BaseWidget):
|
|
|
260
386
|
clone_requested = Signal()
|
|
261
387
|
|
|
262
388
|
def __init__(self, image_path: str, size: int = 128, speed: int = 3,
|
|
263
|
-
behaviour: str = BEHAVIOUR_FLOOR, climb: bool = True):
|
|
389
|
+
behaviour: str = BEHAVIOUR_FLOOR, climb: bool = True, talk: bool = True):
|
|
264
390
|
front_engine_logger.info(
|
|
265
391
|
f"[DesktopPetWidget] Init | path={image_path}, size={size}, speed={speed}, "
|
|
266
|
-
f"behaviour={behaviour}, climb={climb}"
|
|
392
|
+
f"behaviour={behaviour}, climb={climb}, talk={talk}"
|
|
267
393
|
)
|
|
268
394
|
super().__init__()
|
|
269
395
|
self.opacity = 1.0
|
|
270
396
|
self.pet_size: int = max(16, int(size))
|
|
271
397
|
self.image_path: Path = Path(image_path)
|
|
272
|
-
self.movie: Optional[QMovie] = None
|
|
273
|
-
self.pixmap: Optional[QPixmap] = None
|
|
274
398
|
self._dragging: bool = False
|
|
275
399
|
self._drag_offset = None
|
|
276
400
|
self._last_move_delta: Tuple[int, int] = (0, 0)
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
else:
|
|
286
|
-
front_engine_logger.error(f"[DesktopPetWidget] File not found: {self.image_path}")
|
|
401
|
+
# 視覺狀態 -> ("movie"|"pixmap", 物件) / state -> sprite
|
|
402
|
+
self._sprites: dict = {}
|
|
403
|
+
self._active = None
|
|
404
|
+
self._active_state = None
|
|
405
|
+
|
|
406
|
+
self._load_sprites(self.image_path)
|
|
407
|
+
if not self._sprites:
|
|
408
|
+
front_engine_logger.error(f"[DesktopPetWidget] No sprite found: {self.image_path}")
|
|
287
409
|
message_box = QMessageBox(self)
|
|
288
410
|
message_box.setText(language_wrapper.language_word_dict.get("pet_message_box_text", "Pet image not found"))
|
|
289
411
|
message_box.show()
|
|
@@ -292,10 +414,21 @@ class DesktopPetWidget(BaseWidget):
|
|
|
292
414
|
self.motion = PetMotion(
|
|
293
415
|
0, 0, self.pet_size, self.pet_size, (0, 0, 1920, 1080), speed, behaviour, climb=climb
|
|
294
416
|
)
|
|
417
|
+
self._set_active_sprite(STATE_WALK)
|
|
295
418
|
|
|
296
419
|
self._timer = QTimer(self)
|
|
297
420
|
self._timer.timeout.connect(self._on_tick)
|
|
298
421
|
|
|
422
|
+
# Speech bubbles / chatter
|
|
423
|
+
self._talk = bool(talk)
|
|
424
|
+
self._moved = False
|
|
425
|
+
self._chatter_rng = _random_module.SystemRandom()
|
|
426
|
+
self._messages = self._load_messages()
|
|
427
|
+
self._bubble = SpeechBubble()
|
|
428
|
+
self._chatter_timer = QTimer(self)
|
|
429
|
+
self._chatter_timer.setSingleShot(True)
|
|
430
|
+
self._chatter_timer.timeout.connect(self._on_chatter)
|
|
431
|
+
|
|
299
432
|
self.menu = QMenu(self)
|
|
300
433
|
self.clone_action = QAction(language_wrapper.language_word_dict.get("pet_clone", "Clone"), self)
|
|
301
434
|
self.clone_action.triggered.connect(self.clone_requested.emit)
|
|
@@ -308,10 +441,53 @@ class DesktopPetWidget(BaseWidget):
|
|
|
308
441
|
"""寵物需接收滑鼠以便拖曳,故 allow_input=True 並置頂。"""
|
|
309
442
|
apply_overlay_window_flags(self, show_on_bottom=False, allow_input=True)
|
|
310
443
|
|
|
444
|
+
def _load_sprite(self, path: str):
|
|
445
|
+
if Path(path).suffix.lower() in (".gif", ".webp"):
|
|
446
|
+
movie = QMovie(str(path))
|
|
447
|
+
movie.frameChanged.connect(self.update)
|
|
448
|
+
return ("movie", movie)
|
|
449
|
+
return ("pixmap", QPixmap(str(path)))
|
|
450
|
+
|
|
451
|
+
def _load_sprites(self, image_path: Path) -> None:
|
|
452
|
+
"""單一檔 -> 所有狀態共用;資料夾 -> 依檔名對應各狀態。"""
|
|
453
|
+
if image_path.is_dir():
|
|
454
|
+
for state, path in scan_pet_pack(str(image_path)).items():
|
|
455
|
+
self._sprites[state] = self._load_sprite(path)
|
|
456
|
+
elif image_path.is_file():
|
|
457
|
+
self._sprites["default"] = self._load_sprite(str(image_path))
|
|
458
|
+
|
|
459
|
+
def _sprite_for(self, state: str):
|
|
460
|
+
if "default" in self._sprites:
|
|
461
|
+
return self._sprites["default"]
|
|
462
|
+
if state in self._sprites:
|
|
463
|
+
return self._sprites[state]
|
|
464
|
+
for fallback in (STATE_WALK, STATE_IDLE):
|
|
465
|
+
if fallback in self._sprites:
|
|
466
|
+
return self._sprites[fallback]
|
|
467
|
+
return next(iter(self._sprites.values()), None)
|
|
468
|
+
|
|
469
|
+
def _set_active_sprite(self, state: str) -> None:
|
|
470
|
+
sprite = self._sprite_for(state)
|
|
471
|
+
if sprite is None or sprite is self._active:
|
|
472
|
+
return
|
|
473
|
+
if self._active is not None and self._active[0] == "movie":
|
|
474
|
+
self._active[1].stop()
|
|
475
|
+
self._active = sprite
|
|
476
|
+
self._active_state = state
|
|
477
|
+
if sprite[0] == "movie":
|
|
478
|
+
sprite[1].start()
|
|
479
|
+
self.update()
|
|
480
|
+
|
|
481
|
+
def _visual_state(self) -> str:
|
|
482
|
+
return derive_visual_state(
|
|
483
|
+
self._dragging, self.motion._airborne, self.motion.surface, self.motion.state
|
|
484
|
+
)
|
|
485
|
+
|
|
311
486
|
def _current_pixmap(self) -> Optional[QPixmap]:
|
|
312
|
-
if self.
|
|
313
|
-
return
|
|
314
|
-
|
|
487
|
+
if self._active is None:
|
|
488
|
+
return None
|
|
489
|
+
kind, obj = self._active
|
|
490
|
+
return obj.currentPixmap() if kind == "movie" else obj
|
|
315
491
|
|
|
316
492
|
def draw_content(self, painter: QPainter) -> None:
|
|
317
493
|
pixmap = self._current_pixmap()
|
|
@@ -329,28 +505,67 @@ class DesktopPetWidget(BaseWidget):
|
|
|
329
505
|
self.motion.y = float(bottom - self.pet_size)
|
|
330
506
|
self.move(int(self.motion.x), int(self.motion.y))
|
|
331
507
|
self._timer.start(max(10, int(interval_ms)))
|
|
508
|
+
self._schedule_chatter()
|
|
509
|
+
|
|
510
|
+
def _load_messages(self) -> dict:
|
|
511
|
+
d = language_wrapper.language_word_dict
|
|
512
|
+
|
|
513
|
+
def lines(key: str, fallback: str) -> list:
|
|
514
|
+
return [part.strip() for part in str(d.get(key, fallback)).split("|") if part.strip()]
|
|
515
|
+
|
|
516
|
+
return {
|
|
517
|
+
"morning": lines("pet_chatter_morning", "Good morning!|Ready for the day?"),
|
|
518
|
+
"afternoon": lines("pet_chatter_afternoon", "Good afternoon!|Taking a break?"),
|
|
519
|
+
"evening": lines("pet_chatter_evening", "Good evening!|How was your day?"),
|
|
520
|
+
"night": lines("pet_chatter_night", "It's late - get some rest!|Still up?"),
|
|
521
|
+
"any": lines("pet_chatter_any", "Hi there!|(^_^)|Keep going!"),
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
def _schedule_chatter(self) -> None:
|
|
525
|
+
if self._talk:
|
|
526
|
+
self._chatter_timer.start(self._chatter_rng.randint(15000, 35000))
|
|
527
|
+
|
|
528
|
+
def _on_chatter(self) -> None:
|
|
529
|
+
self.say()
|
|
530
|
+
self._schedule_chatter()
|
|
531
|
+
|
|
532
|
+
def say(self, text: Optional[str] = None) -> None:
|
|
533
|
+
"""顯示一句台詞(text 為 None 時依時段隨機挑)。"""
|
|
534
|
+
if not self._talk:
|
|
535
|
+
return
|
|
536
|
+
if text is None:
|
|
537
|
+
text = pick_message(datetime.now().hour, self._chatter_rng, self._messages)
|
|
538
|
+
if text:
|
|
539
|
+
self._bubble.show_message(text, self)
|
|
332
540
|
|
|
333
541
|
def _on_tick(self) -> None:
|
|
334
542
|
if self._dragging:
|
|
543
|
+
self._set_active_sprite(STATE_DRAG)
|
|
335
544
|
return
|
|
336
545
|
if self.motion.behaviour == BEHAVIOUR_CHASE:
|
|
337
546
|
cursor = QCursor.pos()
|
|
338
547
|
self.motion.set_target(cursor.x(), cursor.y())
|
|
339
548
|
x, y = self.motion.step()
|
|
340
549
|
self.move(x, y)
|
|
550
|
+
self._set_active_sprite(self._visual_state())
|
|
551
|
+
if self._bubble.isVisible():
|
|
552
|
+
self._bubble.reposition(self)
|
|
341
553
|
|
|
342
554
|
# --- dragging + throwing ---
|
|
343
555
|
def mousePressEvent(self, event) -> None:
|
|
344
556
|
if event.button() == Qt.MouseButton.LeftButton:
|
|
345
557
|
self._dragging = True
|
|
558
|
+
self._moved = False
|
|
346
559
|
self._last_move_delta = (0, 0)
|
|
347
560
|
self._drag_offset = event.globalPosition().toPoint() - self.frameGeometry().topLeft()
|
|
561
|
+
self._set_active_sprite(STATE_DRAG)
|
|
348
562
|
super().mousePressEvent(event)
|
|
349
563
|
|
|
350
564
|
def mouseMoveEvent(self, event) -> None:
|
|
351
565
|
if self._dragging and self._drag_offset is not None:
|
|
352
566
|
new_top_left = event.globalPosition().toPoint() - self._drag_offset
|
|
353
567
|
self._last_move_delta = (new_top_left.x() - self.x(), new_top_left.y() - self.y())
|
|
568
|
+
self._moved = True
|
|
354
569
|
self.move(new_top_left)
|
|
355
570
|
super().mouseMoveEvent(event)
|
|
356
571
|
|
|
@@ -359,9 +574,12 @@ class DesktopPetWidget(BaseWidget):
|
|
|
359
574
|
self._dragging = False
|
|
360
575
|
self.motion.x = float(self.x())
|
|
361
576
|
self.motion.y = float(self.y())
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
self.motion.
|
|
577
|
+
if self._moved:
|
|
578
|
+
# Fling with the momentum of the last drag movement (floor mode).
|
|
579
|
+
if self.motion.behaviour == BEHAVIOUR_FLOOR:
|
|
580
|
+
self.motion.throw(self._last_move_delta[0], self._last_move_delta[1])
|
|
581
|
+
else:
|
|
582
|
+
self.say() # a click (no drag) makes the pet talk
|
|
365
583
|
super().mouseReleaseEvent(event)
|
|
366
584
|
|
|
367
585
|
def contextMenuEvent(self, event) -> None:
|
|
@@ -370,6 +588,10 @@ class DesktopPetWidget(BaseWidget):
|
|
|
370
588
|
def closeEvent(self, event) -> None:
|
|
371
589
|
if self._timer.isActive():
|
|
372
590
|
self._timer.stop()
|
|
373
|
-
if self.
|
|
374
|
-
self.
|
|
591
|
+
if self._chatter_timer.isActive():
|
|
592
|
+
self._chatter_timer.stop()
|
|
593
|
+
self._bubble.close()
|
|
594
|
+
for kind, obj in self._sprites.values():
|
|
595
|
+
if kind == "movie":
|
|
596
|
+
obj.stop()
|
|
375
597
|
super().closeEvent(event)
|
|
@@ -2,11 +2,11 @@ from typing import Optional
|
|
|
2
2
|
|
|
3
3
|
from PySide6.QtGui import QGuiApplication
|
|
4
4
|
from PySide6.QtWidgets import (
|
|
5
|
-
QWidget, QGridLayout, QLabel, QPushButton, QMessageBox, QComboBox, QCheckBox,
|
|
5
|
+
QWidget, QGridLayout, QLabel, QPushButton, QMessageBox, QComboBox, QCheckBox, QFileDialog,
|
|
6
6
|
)
|
|
7
7
|
|
|
8
8
|
from frontengine.show.pet.desktop_pet import (
|
|
9
|
-
DesktopPetWidget, BEHAVIOUR_FLOOR, BEHAVIOUR_WANDER, BEHAVIOUR_CHASE,
|
|
9
|
+
DesktopPetWidget, BEHAVIOUR_FLOOR, BEHAVIOUR_WANDER, BEHAVIOUR_CHASE, scan_pet_pack,
|
|
10
10
|
)
|
|
11
11
|
from frontengine.ui.dialog.choose_file_dialog import choose_pet
|
|
12
12
|
from frontengine.ui.page.utils import (
|
|
@@ -38,6 +38,10 @@ class PetSettingUI(QWidget):
|
|
|
38
38
|
language_wrapper.language_word_dict.get("pet_choose_file", "Choose pet sprite")
|
|
39
39
|
)
|
|
40
40
|
self.choose_file_button.clicked.connect(self.choose_and_play)
|
|
41
|
+
self.choose_pack_button = QPushButton(
|
|
42
|
+
language_wrapper.language_word_dict.get("pet_choose_pack", "Choose pet pack...")
|
|
43
|
+
)
|
|
44
|
+
self.choose_pack_button.clicked.connect(self.choose_pack)
|
|
41
45
|
self.ready_label = QLabel(language_wrapper.language_word_dict.get("Not Ready"))
|
|
42
46
|
|
|
43
47
|
# Size
|
|
@@ -65,6 +69,8 @@ class PetSettingUI(QWidget):
|
|
|
65
69
|
# Climb walls / ceiling (only meaningful in floor mode)
|
|
66
70
|
self.climb_checkbox = QCheckBox(language_wrapper.language_word_dict.get("pet_climb_label", "Climb walls"))
|
|
67
71
|
self.climb_checkbox.setChecked(True)
|
|
72
|
+
self.talk_checkbox = QCheckBox(language_wrapper.language_word_dict.get("pet_talk_label", "Speech bubbles"))
|
|
73
|
+
self.talk_checkbox.setChecked(True)
|
|
68
74
|
|
|
69
75
|
# Start
|
|
70
76
|
self.start_button = QPushButton(language_wrapper.language_word_dict.get("pet_start", "Spawn pet"))
|
|
@@ -81,6 +87,7 @@ class PetSettingUI(QWidget):
|
|
|
81
87
|
# Layout
|
|
82
88
|
self.grid_layout.addWidget(self.choose_file_button, 0, 0)
|
|
83
89
|
self.grid_layout.addWidget(self.ready_label, 0, 1)
|
|
90
|
+
self.grid_layout.addWidget(self.choose_pack_button, 0, 2)
|
|
84
91
|
self.grid_layout.addWidget(self.size_label, 1, 0)
|
|
85
92
|
self.grid_layout.addWidget(self.size_combobox, 1, 1)
|
|
86
93
|
self.grid_layout.addWidget(self.speed_label, 2, 0)
|
|
@@ -88,6 +95,7 @@ class PetSettingUI(QWidget):
|
|
|
88
95
|
self.grid_layout.addWidget(self.behaviour_label, 3, 0)
|
|
89
96
|
self.grid_layout.addWidget(self.behaviour_combobox, 3, 1)
|
|
90
97
|
self.grid_layout.addWidget(self.climb_checkbox, 3, 2)
|
|
98
|
+
self.grid_layout.addWidget(self.talk_checkbox, 2, 2)
|
|
91
99
|
self.grid_layout.addWidget(self.start_button, 4, 0)
|
|
92
100
|
self.grid_layout.addWidget(self.recent_files_label, 5, 0)
|
|
93
101
|
self.grid_layout.addWidget(self.recent_files_combobox, 5, 1)
|
|
@@ -102,6 +110,7 @@ class PetSettingUI(QWidget):
|
|
|
102
110
|
speed=int(self.speed_combobox.currentText()),
|
|
103
111
|
behaviour=self.behaviour_combobox.currentData(),
|
|
104
112
|
climb=self.climb_checkbox.isChecked(),
|
|
113
|
+
talk=self.talk_checkbox.isChecked(),
|
|
105
114
|
)
|
|
106
115
|
pet.clone_requested.connect(self._spawn_pet)
|
|
107
116
|
pet.set_pet_window_flag()
|
|
@@ -132,6 +141,28 @@ class PetSettingUI(QWidget):
|
|
|
132
141
|
add_recent_file("pet", self.pet_image_path)
|
|
133
142
|
reload_recent_combobox(self.recent_files_combobox, "pet")
|
|
134
143
|
|
|
144
|
+
def choose_pack(self) -> None:
|
|
145
|
+
"""選擇動作包資料夾(依 walk/idle/climb/fall/drag 檔名對應狀態)。"""
|
|
146
|
+
front_engine_logger.info("[PetSettingUI] choose_pack")
|
|
147
|
+
folder = QFileDialog.getExistingDirectory(
|
|
148
|
+
self, language_wrapper.language_word_dict.get("pet_choose_pack", "Choose pet pack...")
|
|
149
|
+
)
|
|
150
|
+
if not folder:
|
|
151
|
+
return
|
|
152
|
+
if not scan_pet_pack(folder):
|
|
153
|
+
QMessageBox.warning(
|
|
154
|
+
self,
|
|
155
|
+
language_wrapper.language_word_dict.get("pet_choose_pack", "Choose pet pack..."),
|
|
156
|
+
language_wrapper.language_word_dict.get(
|
|
157
|
+
"pet_pack_empty", "No sprites (walk/idle/climb/fall/drag) found in that folder."),
|
|
158
|
+
)
|
|
159
|
+
return
|
|
160
|
+
self.pet_image_path = folder
|
|
161
|
+
self.ready_to_play = True
|
|
162
|
+
self.ready_label.setText(language_wrapper.language_word_dict.get("Ready"))
|
|
163
|
+
add_recent_file("pet", folder)
|
|
164
|
+
reload_recent_combobox(self.recent_files_combobox, "pet")
|
|
165
|
+
|
|
135
166
|
def _apply_recent_file(self, _index: int = 0) -> None:
|
|
136
167
|
path = self.recent_files_combobox.currentData()
|
|
137
168
|
self.recent_files_combobox.setCurrentIndex(0)
|
|
@@ -156,6 +187,7 @@ class PetSettingUI(QWidget):
|
|
|
156
187
|
"speed": self.speed_combobox.currentText(),
|
|
157
188
|
"behaviour": self.behaviour_combobox.currentData(),
|
|
158
189
|
"climb": self.climb_checkbox.isChecked(),
|
|
190
|
+
"talk": self.talk_checkbox.isChecked(),
|
|
159
191
|
}
|
|
160
192
|
|
|
161
193
|
def set_state(self, state: dict) -> None:
|
|
@@ -177,3 +209,5 @@ class PetSettingUI(QWidget):
|
|
|
177
209
|
self.behaviour_combobox.setCurrentIndex(index)
|
|
178
210
|
if "climb" in state:
|
|
179
211
|
self.climb_checkbox.setChecked(bool(state["climb"]))
|
|
212
|
+
if "talk" in state:
|
|
213
|
+
self.talk_checkbox.setChecked(bool(state["talk"]))
|
|
@@ -225,6 +225,14 @@ english_word_dict = {
|
|
|
225
225
|
"pet_behaviour_chase": "Chase cursor",
|
|
226
226
|
"pet_climb_label": "Climb walls",
|
|
227
227
|
"pet_clone": "Clone",
|
|
228
|
+
"pet_choose_pack": "Choose pet pack...",
|
|
229
|
+
"pet_pack_empty": "No sprites (walk/idle/climb/fall/drag) found in that folder.",
|
|
230
|
+
"pet_talk_label": "Speech bubbles",
|
|
231
|
+
"pet_chatter_morning": "Good morning!|Rise and shine!|Ready for the day?",
|
|
232
|
+
"pet_chatter_afternoon": "Good afternoon!|Taking a break?|Keep it up!",
|
|
233
|
+
"pet_chatter_evening": "Good evening!|How was your day?|Almost done?",
|
|
234
|
+
"pet_chatter_night": "It's late - get some rest!|Still up?|Sweet dreams soon~",
|
|
235
|
+
"pet_chatter_any": "Hi there!|(^_^)|Keep going!|You've got this!",
|
|
228
236
|
"pet_start": "Spawn pet",
|
|
229
237
|
"pet_message_box_text": "Pet image not found",
|
|
230
238
|
}
|
{frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/multi_language/traditional_chinese.py
RENAMED
|
@@ -226,6 +226,14 @@ traditional_chinese_word_dict = {
|
|
|
226
226
|
"pet_behaviour_chase": "追逐游標",
|
|
227
227
|
"pet_climb_label": "攀爬牆壁",
|
|
228
228
|
"pet_clone": "複製",
|
|
229
|
+
"pet_choose_pack": "選擇動作包資料夾...",
|
|
230
|
+
"pet_pack_empty": "該資料夾找不到精靈檔(walk/idle/climb/fall/drag)。",
|
|
231
|
+
"pet_talk_label": "對話泡泡",
|
|
232
|
+
"pet_chatter_morning": "早安!|新的一天開始囉!|準備好了嗎?",
|
|
233
|
+
"pet_chatter_afternoon": "午安!|要不要休息一下?|繼續加油!",
|
|
234
|
+
"pet_chatter_evening": "晚上好!|今天過得如何?|快完成了嗎?",
|
|
235
|
+
"pet_chatter_night": "很晚了,早點休息!|還沒睡嗎?|祝好夢~",
|
|
236
|
+
"pet_chatter_any": "嗨!|(^_^)|加油!|你可以的!",
|
|
229
237
|
"pet_start": "召喚寵物",
|
|
230
238
|
"pet_message_box_text": "找不到寵物圖片",
|
|
231
239
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frontengine
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.6
|
|
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.4 → frontengine-1.0.6}/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
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/image.py
RENAMED
|
File without changes
|
{frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/registry.py
RENAMED
|
File without changes
|
{frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/sound.py
RENAMED
|
File without changes
|
{frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/text.py
RENAMED
|
File without changes
|
{frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_page/video.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.4 → frontengine-1.0.6}/frontengine/ui/page/scene_setting/scene_setting_ui.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.4 → frontengine-1.0.6}/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.4 → frontengine-1.0.6}/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.4 → frontengine-1.0.6}/frontengine/utils/multi_language/language_wrapper.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/multi_language/simplified_chinese.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/preset_schedule/preset_schedule_service.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/redirect_manager/redirect_manager_class.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.4 → frontengine-1.0.6}/frontengine/utils/smart_pause/smart_pause_service.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.4 → frontengine-1.0.6}/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
|