frontengine 1.0.7__tar.gz → 1.0.9__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.7 → frontengine-1.0.9}/PKG-INFO +1 -1
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/pet/desktop_pet.py +88 -11
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/pet/pet_setting_ui.py +18 -1
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/user_setting/user_setting_file.py +3 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/multi_language/english.py +3 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/multi_language/traditional_chinese.py +3 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine.egg-info/PKG-INFO +1 -1
- {frontengine-1.0.7 → frontengine-1.0.9}/pyproject.toml +1 -1
- {frontengine-1.0.7 → frontengine-1.0.9}/LICENSE +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/README.md +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/__main__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/base_widget.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/gif/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/gif/paint_gif.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/image/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/image/paint_image.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/load/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/load/load_someone_make_ui.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/overlay_factory.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/particle/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/particle/particle_ui.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/pet/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/scene/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/scene/extend_graphic_scene.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/scene/extend_graphic_view.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/scene/scene.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/sound_player/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/sound_player/sound_effect.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/sound_player/sound_player.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/text/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/text/draw_text.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/video/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/video/video_player.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/web/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/web/webview.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/show/window_helpers.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/system_tray/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/system_tray/extend_system_tray.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/color/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/color/global_color.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/dialog/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/dialog/choose_file_dialog.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/dialog/hotkey_settings_dialog.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/dialog/save_file_dialog.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/main_ui.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/menu/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/menu/help_menu.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/menu/how_to_menu.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/menu/language_menu.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/menu/preset_menu.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/menu/settings_menu.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/control_center/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/control_center/control_center_ui.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/gif/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/gif/gif_setting_ui.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/image/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/image/image_setting_ui.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/particle/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/particle/particle_setting_ui.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/pet/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_manager.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/base_scene_page.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/gif.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/image.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/registry.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/sound.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/text.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/video.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/web.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_setting_ui.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/sound_player/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/sound_player/sound_player_setting_ui.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/text/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/text/text_setting_ui.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/utils.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/video/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/video/video_setting_ui.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/web/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/web/web_setting_ui.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/user_setting/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/user_setting/preset_repository.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/user_setting/scene_setting.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/browser/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/browser/browser.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/critical_exit/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/critical_exit/check_key_is_press.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/critical_exit/critical_exit.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/critical_exit/win32_vk.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/exception/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/exception/exception_tags.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/exception/exceptions.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/file/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/file/open/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/file/open/open_file.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/file/save/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/file/save/save_file.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/hotkey/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/hotkey/hotkey_service.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/json/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/json/json_file.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/json/json_repository.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/json_format/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/json_format/json_process.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/logging/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/logging/loggin_instance.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/multi_language/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/multi_language/france.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/multi_language/germany.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/multi_language/italy.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/multi_language/language_wrapper.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/multi_language/russian.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/multi_language/simplified_chinese.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/preset_schedule/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/preset_schedule/preset_schedule_service.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/redirect_manager/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/redirect_manager/redirect_manager_class.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/smart_pause/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/smart_pause/smart_pause_service.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/theme_schedule/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/theme_schedule/theme_schedule_service.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/web_url.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/worker/__init__.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine/worker/qthread_worker.py +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine.egg-info/SOURCES.txt +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine.egg-info/dependency_links.txt +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine.egg-info/entry_points.txt +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine.egg-info/requires.txt +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/frontengine.egg-info/top_level.txt +0 -0
- {frontengine-1.0.7 → frontengine-1.0.9}/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.9
|
|
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
|
|
@@ -3,12 +3,14 @@ from datetime import datetime
|
|
|
3
3
|
from pathlib import Path
|
|
4
4
|
from typing import Optional, Tuple
|
|
5
5
|
|
|
6
|
-
from PySide6.QtCore import Qt, QRect, QTimer, Signal
|
|
6
|
+
from PySide6.QtCore import Qt, QRect, QTimer, QUrl, Signal
|
|
7
7
|
from PySide6.QtGui import QAction, QColor, QCursor, QFont, QFontMetrics, QMovie, QPainter, QPixmap, QTransform
|
|
8
|
+
from PySide6.QtMultimedia import QSoundEffect
|
|
8
9
|
from PySide6.QtWidgets import QMenu, QMessageBox, QWidget
|
|
9
10
|
|
|
10
11
|
from frontengine.show.base_widget import BaseWidget
|
|
11
12
|
from frontengine.show.window_helpers import apply_overlay_window_flags
|
|
13
|
+
from frontengine.user_setting.user_setting_file import user_setting_dict
|
|
12
14
|
from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
13
15
|
from frontengine.utils.multi_language.language_wrapper import language_wrapper
|
|
14
16
|
|
|
@@ -106,18 +108,56 @@ def message_bucket(hour: int) -> str:
|
|
|
106
108
|
return "night"
|
|
107
109
|
|
|
108
110
|
|
|
109
|
-
def pick_message(hour: int, rng, messages: dict) -> str:
|
|
111
|
+
def pick_message(hour: int, rng, messages: dict, mood: Optional[str] = None) -> str:
|
|
110
112
|
"""
|
|
111
|
-
|
|
112
|
-
Pick a chatter line
|
|
113
|
-
|
|
113
|
+
挑一句台詞:先放心情句庫(若有),再放時段句庫、通用句庫。皆空回傳空字串。
|
|
114
|
+
Pick a chatter line: mood pool (if any) first, then the time-of-day pool,
|
|
115
|
+
then the generic pool. rng needs ``randrange``.
|
|
114
116
|
"""
|
|
115
|
-
pool =
|
|
117
|
+
pool = []
|
|
118
|
+
if mood and mood in messages:
|
|
119
|
+
pool += list(messages[mood])
|
|
120
|
+
pool += list(messages.get(message_bucket(hour), []))
|
|
121
|
+
pool += list(messages.get("any", []))
|
|
116
122
|
if not pool:
|
|
117
123
|
return ""
|
|
118
124
|
return pool[rng.randrange(len(pool))]
|
|
119
125
|
|
|
120
126
|
|
|
127
|
+
class PetMood:
|
|
128
|
+
"""
|
|
129
|
+
寵物心情值 0~100:互動會上升、被忽略會慢慢下降;level() 回傳 happy/content/sad。
|
|
130
|
+
Pet happiness 0..100: petting raises it, neglect decays it; level() buckets it.
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
HAPPY = "happy"
|
|
134
|
+
CONTENT = "content"
|
|
135
|
+
SAD = "sad"
|
|
136
|
+
|
|
137
|
+
def __init__(self, value: int = 60) -> None:
|
|
138
|
+
self.value = self._clamp(value)
|
|
139
|
+
|
|
140
|
+
@staticmethod
|
|
141
|
+
def _clamp(value) -> int:
|
|
142
|
+
try:
|
|
143
|
+
return max(0, min(100, int(value)))
|
|
144
|
+
except (TypeError, ValueError):
|
|
145
|
+
return 60
|
|
146
|
+
|
|
147
|
+
def pet(self, amount: int = 12) -> None:
|
|
148
|
+
self.value = self._clamp(self.value + amount)
|
|
149
|
+
|
|
150
|
+
def decay(self, amount: int = 1) -> None:
|
|
151
|
+
self.value = self._clamp(self.value - amount)
|
|
152
|
+
|
|
153
|
+
def level(self) -> str:
|
|
154
|
+
if self.value >= 70:
|
|
155
|
+
return self.HAPPY
|
|
156
|
+
if self.value <= 30:
|
|
157
|
+
return self.SAD
|
|
158
|
+
return self.CONTENT
|
|
159
|
+
|
|
160
|
+
|
|
121
161
|
class SpeechBubble(QWidget):
|
|
122
162
|
"""寵物頭上的小對話泡泡,數秒後自動消失 / A small speech bubble that auto-hides."""
|
|
123
163
|
|
|
@@ -412,10 +452,11 @@ class DesktopPetWidget(BaseWidget):
|
|
|
412
452
|
clone_requested = Signal()
|
|
413
453
|
|
|
414
454
|
def __init__(self, image_path: str, size: int = 128, speed: int = 3,
|
|
415
|
-
behaviour: str = BEHAVIOUR_FLOOR, climb: bool = True, talk: bool = True
|
|
455
|
+
behaviour: str = BEHAVIOUR_FLOOR, climb: bool = True, talk: bool = True,
|
|
456
|
+
sound_path: Optional[str] = None):
|
|
416
457
|
front_engine_logger.info(
|
|
417
458
|
f"[DesktopPetWidget] Init | path={image_path}, size={size}, speed={speed}, "
|
|
418
|
-
f"behaviour={behaviour}, climb={climb}, talk={talk}"
|
|
459
|
+
f"behaviour={behaviour}, climb={climb}, talk={talk}, sound={sound_path}"
|
|
419
460
|
)
|
|
420
461
|
super().__init__()
|
|
421
462
|
self.opacity = 1.0
|
|
@@ -445,11 +486,14 @@ class DesktopPetWidget(BaseWidget):
|
|
|
445
486
|
self._timer = QTimer(self)
|
|
446
487
|
self._timer.timeout.connect(self._on_tick)
|
|
447
488
|
|
|
448
|
-
# Speech bubbles / chatter
|
|
489
|
+
# Speech bubbles / chatter / mood
|
|
449
490
|
self._talk = bool(talk)
|
|
450
491
|
self._moved = False
|
|
451
492
|
self._chatter_rng = _random_module.SystemRandom()
|
|
493
|
+
self._mood = PetMood(user_setting_dict.get("pet_mood", 60))
|
|
452
494
|
self._messages = self._load_messages()
|
|
495
|
+
self._sound: Optional[QSoundEffect] = None
|
|
496
|
+
self._init_sound(sound_path)
|
|
453
497
|
self._bubble = SpeechBubble()
|
|
454
498
|
self._chatter_timer = QTimer(self)
|
|
455
499
|
self._chatter_timer.setSingleShot(True)
|
|
@@ -544,23 +588,53 @@ class DesktopPetWidget(BaseWidget):
|
|
|
544
588
|
"afternoon": lines("pet_chatter_afternoon", "Good afternoon!|Taking a break?"),
|
|
545
589
|
"evening": lines("pet_chatter_evening", "Good evening!|How was your day?"),
|
|
546
590
|
"night": lines("pet_chatter_night", "It's late - get some rest!|Still up?"),
|
|
591
|
+
"happy": lines("pet_chatter_happy", "I'm so happy!|You're the best!|(^o^)"),
|
|
592
|
+
"sad": lines("pet_chatter_sad", "Feeling a bit lonely...|Pet me?|(._.)"),
|
|
547
593
|
"any": lines("pet_chatter_any", "Hi there!|(^_^)|Keep going!"),
|
|
548
594
|
}
|
|
549
595
|
|
|
596
|
+
def _persist_mood(self) -> None:
|
|
597
|
+
user_setting_dict["pet_mood"] = self._mood.value
|
|
598
|
+
|
|
599
|
+
def _init_sound(self, sound_path: Optional[str]) -> None:
|
|
600
|
+
if not sound_path:
|
|
601
|
+
return
|
|
602
|
+
path = Path(sound_path)
|
|
603
|
+
if not (path.exists() and path.is_file()):
|
|
604
|
+
return
|
|
605
|
+
try:
|
|
606
|
+
self._sound = QSoundEffect(self)
|
|
607
|
+
self._sound.setSource(QUrl.fromLocalFile(str(path)))
|
|
608
|
+
except Exception as error: # pragma: no cover - audio backend guard
|
|
609
|
+
front_engine_logger.warning(f"[DesktopPetWidget] sound load failed: {error!r}")
|
|
610
|
+
self._sound = None
|
|
611
|
+
|
|
612
|
+
def _play_sound(self) -> None:
|
|
613
|
+
if self._sound is None:
|
|
614
|
+
return
|
|
615
|
+
try:
|
|
616
|
+
self._sound.play()
|
|
617
|
+
except Exception as error: # pragma: no cover - audio backend guard
|
|
618
|
+
front_engine_logger.warning(f"[DesktopPetWidget] sound play failed: {error!r}")
|
|
619
|
+
|
|
550
620
|
def _schedule_chatter(self) -> None:
|
|
551
621
|
if self._talk:
|
|
552
622
|
self._chatter_timer.start(self._chatter_rng.randint(15000, 35000))
|
|
553
623
|
|
|
554
624
|
def _on_chatter(self) -> None:
|
|
625
|
+
self._mood.decay() # a little neglect over time
|
|
626
|
+
self._persist_mood()
|
|
555
627
|
self.say()
|
|
556
628
|
self._schedule_chatter()
|
|
557
629
|
|
|
558
630
|
def say(self, text: Optional[str] = None) -> None:
|
|
559
|
-
"""顯示一句台詞(text 為 None
|
|
631
|
+
"""顯示一句台詞(text 為 None 時依心情/時段隨機挑)。"""
|
|
560
632
|
if not self._talk:
|
|
561
633
|
return
|
|
562
634
|
if text is None:
|
|
563
|
-
|
|
635
|
+
level = self._mood.level()
|
|
636
|
+
mood = level if level in (PetMood.HAPPY, PetMood.SAD) else None
|
|
637
|
+
text = pick_message(datetime.now().hour, self._chatter_rng, self._messages, mood=mood)
|
|
564
638
|
if text:
|
|
565
639
|
self._bubble.show_message(text, self)
|
|
566
640
|
|
|
@@ -585,6 +659,9 @@ class DesktopPetWidget(BaseWidget):
|
|
|
585
659
|
self._last_move_delta = (0, 0)
|
|
586
660
|
self._drag_offset = event.globalPosition().toPoint() - self.frameGeometry().topLeft()
|
|
587
661
|
self.motion.wake() # interacting wakes a sleeping pet
|
|
662
|
+
self._mood.pet() # petting cheers it up
|
|
663
|
+
self._persist_mood()
|
|
664
|
+
self._play_sound()
|
|
588
665
|
self._set_active_sprite(STATE_DRAG)
|
|
589
666
|
super().mousePressEvent(event)
|
|
590
667
|
|
|
@@ -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
|
|
@@ -88,6 +93,7 @@ class PetSettingUI(QWidget):
|
|
|
88
93
|
self.grid_layout.addWidget(self.choose_file_button, 0, 0)
|
|
89
94
|
self.grid_layout.addWidget(self.ready_label, 0, 1)
|
|
90
95
|
self.grid_layout.addWidget(self.choose_pack_button, 0, 2)
|
|
96
|
+
self.grid_layout.addWidget(self.choose_sound_button, 1, 2)
|
|
91
97
|
self.grid_layout.addWidget(self.size_label, 1, 0)
|
|
92
98
|
self.grid_layout.addWidget(self.size_combobox, 1, 1)
|
|
93
99
|
self.grid_layout.addWidget(self.speed_label, 2, 0)
|
|
@@ -111,6 +117,7 @@ class PetSettingUI(QWidget):
|
|
|
111
117
|
behaviour=self.behaviour_combobox.currentData(),
|
|
112
118
|
climb=self.climb_checkbox.isChecked(),
|
|
113
119
|
talk=self.talk_checkbox.isChecked(),
|
|
120
|
+
sound_path=self.pet_sound_path,
|
|
114
121
|
)
|
|
115
122
|
pet.clone_requested.connect(self._spawn_pet)
|
|
116
123
|
pet.set_pet_window_flag()
|
|
@@ -141,6 +148,13 @@ class PetSettingUI(QWidget):
|
|
|
141
148
|
add_recent_file("pet", self.pet_image_path)
|
|
142
149
|
reload_recent_combobox(self.recent_files_combobox, "pet")
|
|
143
150
|
|
|
151
|
+
def choose_sound(self) -> None:
|
|
152
|
+
"""選擇點擊時播放的音效(選填)/ Choose an optional click sound."""
|
|
153
|
+
front_engine_logger.info("[PetSettingUI] choose_sound")
|
|
154
|
+
path = choose_wav_sound(self)
|
|
155
|
+
if path:
|
|
156
|
+
self.pet_sound_path = path
|
|
157
|
+
|
|
144
158
|
def choose_pack(self) -> None:
|
|
145
159
|
"""選擇動作包資料夾(依 walk/idle/climb/fall/drag 檔名對應狀態)。"""
|
|
146
160
|
front_engine_logger.info("[PetSettingUI] choose_pack")
|
|
@@ -188,6 +202,7 @@ class PetSettingUI(QWidget):
|
|
|
188
202
|
"behaviour": self.behaviour_combobox.currentData(),
|
|
189
203
|
"climb": self.climb_checkbox.isChecked(),
|
|
190
204
|
"talk": self.talk_checkbox.isChecked(),
|
|
205
|
+
"sound": self.pet_sound_path,
|
|
191
206
|
}
|
|
192
207
|
|
|
193
208
|
def set_state(self, state: dict) -> None:
|
|
@@ -211,3 +226,5 @@ class PetSettingUI(QWidget):
|
|
|
211
226
|
self.climb_checkbox.setChecked(bool(state["climb"]))
|
|
212
227
|
if "talk" in state:
|
|
213
228
|
self.talk_checkbox.setChecked(bool(state["talk"]))
|
|
229
|
+
if state.get("sound"):
|
|
230
|
+
self.pet_sound_path = str(state["sound"])
|
|
@@ -33,6 +33,9 @@ user_setting_dict: Dict[str, Any] = {
|
|
|
33
33
|
# 每天在指定時間自動套用預設集
|
|
34
34
|
# Auto-apply a preset at a configured time each day
|
|
35
35
|
"preset_schedule": dict(DEFAULT_PRESET_SCHEDULE),
|
|
36
|
+
# 桌面寵物心情值(0~100),跨工作階段保存
|
|
37
|
+
# Desktop pet mood (0..100), persisted across sessions
|
|
38
|
+
"pet_mood": 60,
|
|
36
39
|
}
|
|
37
40
|
|
|
38
41
|
|
|
@@ -226,6 +226,7 @@ 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",
|
|
231
232
|
"pet_chatter_morning": "Good morning!|Rise and shine!|Ready for the day?",
|
|
@@ -233,6 +234,8 @@ english_word_dict = {
|
|
|
233
234
|
"pet_chatter_evening": "Good evening!|How was your day?|Almost done?",
|
|
234
235
|
"pet_chatter_night": "It's late - get some rest!|Still up?|Sweet dreams soon~",
|
|
235
236
|
"pet_chatter_any": "Hi there!|(^_^)|Keep going!|You've got this!",
|
|
237
|
+
"pet_chatter_happy": "I'm so happy!|You're the best!|(^o^)/|Best day ever!",
|
|
238
|
+
"pet_chatter_sad": "Feeling a bit lonely...|Pet me?|(._.)|Don't forget about me~",
|
|
236
239
|
"pet_start": "Spawn pet",
|
|
237
240
|
"pet_message_box_text": "Pet image not found",
|
|
238
241
|
}
|
{frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/multi_language/traditional_chinese.py
RENAMED
|
@@ -227,6 +227,7 @@ 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": "對話泡泡",
|
|
232
233
|
"pet_chatter_morning": "早安!|新的一天開始囉!|準備好了嗎?",
|
|
@@ -234,6 +235,8 @@ traditional_chinese_word_dict = {
|
|
|
234
235
|
"pet_chatter_evening": "晚上好!|今天過得如何?|快完成了嗎?",
|
|
235
236
|
"pet_chatter_night": "很晚了,早點休息!|還沒睡嗎?|祝好夢~",
|
|
236
237
|
"pet_chatter_any": "嗨!|(^_^)|加油!|你可以的!",
|
|
238
|
+
"pet_chatter_happy": "我好開心!|你最棒了!|(^o^)/|今天真美好!",
|
|
239
|
+
"pet_chatter_sad": "有點寂寞…|摸摸我好嗎?|(._.)|別忘了我~",
|
|
237
240
|
"pet_start": "召喚寵物",
|
|
238
241
|
"pet_message_box_text": "找不到寵物圖片",
|
|
239
242
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frontengine
|
|
3
|
-
Version: 1.0.
|
|
3
|
+
Version: 1.0.9
|
|
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.7 → frontengine-1.0.9}/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.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/image.py
RENAMED
|
File without changes
|
{frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/registry.py
RENAMED
|
File without changes
|
{frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/sound.py
RENAMED
|
File without changes
|
{frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/text.py
RENAMED
|
File without changes
|
{frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_page/video.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.7 → frontengine-1.0.9}/frontengine/ui/page/scene_setting/scene_setting_ui.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.7 → frontengine-1.0.9}/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
|
{frontengine-1.0.7 → frontengine-1.0.9}/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.7 → frontengine-1.0.9}/frontengine/utils/multi_language/language_wrapper.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/multi_language/simplified_chinese.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/preset_schedule/preset_schedule_service.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/redirect_manager/redirect_manager_class.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.7 → frontengine-1.0.9}/frontengine/utils/smart_pause/smart_pause_service.py
RENAMED
|
File without changes
|
|
File without changes
|
{frontengine-1.0.7 → frontengine-1.0.9}/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
|