frontengine 1.0.14__tar.gz → 1.0.16__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (136) hide show
  1. {frontengine-1.0.14 → frontengine-1.0.16}/PKG-INFO +1 -1
  2. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/pet/desktop_pet.py +129 -1
  3. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/user_setting/user_setting_file.py +3 -0
  4. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/multi_language/english.py +4 -0
  5. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/multi_language/traditional_chinese.py +4 -0
  6. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine.egg-info/PKG-INFO +1 -1
  7. {frontengine-1.0.14 → frontengine-1.0.16}/pyproject.toml +1 -1
  8. {frontengine-1.0.14 → frontengine-1.0.16}/LICENSE +0 -0
  9. {frontengine-1.0.14 → frontengine-1.0.16}/README.md +0 -0
  10. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/__init__.py +0 -0
  11. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/__main__.py +0 -0
  12. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/__init__.py +0 -0
  13. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/base_widget.py +0 -0
  14. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/gif/__init__.py +0 -0
  15. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/gif/paint_gif.py +0 -0
  16. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/image/__init__.py +0 -0
  17. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/image/paint_image.py +0 -0
  18. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/load/__init__.py +0 -0
  19. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/load/load_someone_make_ui.py +0 -0
  20. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/overlay_factory.py +0 -0
  21. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/particle/__init__.py +0 -0
  22. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/particle/particle_ui.py +0 -0
  23. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/pet/__init__.py +0 -0
  24. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/scene/__init__.py +0 -0
  25. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/scene/extend_graphic_scene.py +0 -0
  26. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/scene/extend_graphic_view.py +0 -0
  27. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/scene/scene.py +0 -0
  28. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/sound_player/__init__.py +0 -0
  29. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/sound_player/sound_effect.py +0 -0
  30. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/sound_player/sound_player.py +0 -0
  31. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/text/__init__.py +0 -0
  32. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/text/draw_text.py +0 -0
  33. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/video/__init__.py +0 -0
  34. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/video/video_player.py +0 -0
  35. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/web/__init__.py +0 -0
  36. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/web/webview.py +0 -0
  37. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/show/window_helpers.py +0 -0
  38. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/system_tray/__init__.py +0 -0
  39. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/system_tray/extend_system_tray.py +0 -0
  40. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/__init__.py +0 -0
  41. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/color/__init__.py +0 -0
  42. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/color/global_color.py +0 -0
  43. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/dialog/__init__.py +0 -0
  44. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/dialog/choose_file_dialog.py +0 -0
  45. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/dialog/hotkey_settings_dialog.py +0 -0
  46. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/dialog/save_file_dialog.py +0 -0
  47. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/main_ui.py +0 -0
  48. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/menu/__init__.py +0 -0
  49. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/menu/help_menu.py +0 -0
  50. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/menu/how_to_menu.py +0 -0
  51. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/menu/language_menu.py +0 -0
  52. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/menu/preset_menu.py +0 -0
  53. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/menu/settings_menu.py +0 -0
  54. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/__init__.py +0 -0
  55. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/control_center/__init__.py +0 -0
  56. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/control_center/control_center_ui.py +0 -0
  57. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/gif/__init__.py +0 -0
  58. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/gif/gif_setting_ui.py +0 -0
  59. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/image/__init__.py +0 -0
  60. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/image/image_setting_ui.py +0 -0
  61. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/particle/__init__.py +0 -0
  62. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/particle/particle_setting_ui.py +0 -0
  63. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/pet/__init__.py +0 -0
  64. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/pet/pet_setting_ui.py +0 -0
  65. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/scene_setting/__init__.py +0 -0
  66. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/scene_setting/scene_manager.py +0 -0
  67. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/scene_setting/scene_page/__init__.py +0 -0
  68. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/scene_setting/scene_page/base_scene_page.py +0 -0
  69. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/scene_setting/scene_page/gif.py +0 -0
  70. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/scene_setting/scene_page/image.py +0 -0
  71. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/scene_setting/scene_page/registry.py +0 -0
  72. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/scene_setting/scene_page/sound.py +0 -0
  73. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/scene_setting/scene_page/text.py +0 -0
  74. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/scene_setting/scene_page/video.py +0 -0
  75. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/scene_setting/scene_page/web.py +0 -0
  76. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/scene_setting/scene_setting_ui.py +0 -0
  77. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/sound_player/__init__.py +0 -0
  78. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/sound_player/sound_player_setting_ui.py +0 -0
  79. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/text/__init__.py +0 -0
  80. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/text/text_setting_ui.py +0 -0
  81. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/utils.py +0 -0
  82. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/video/__init__.py +0 -0
  83. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/video/video_setting_ui.py +0 -0
  84. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/web/__init__.py +0 -0
  85. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/ui/page/web/web_setting_ui.py +0 -0
  86. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/user_setting/__init__.py +0 -0
  87. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/user_setting/preset_repository.py +0 -0
  88. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/user_setting/scene_setting.py +0 -0
  89. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/__init__.py +0 -0
  90. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/browser/__init__.py +0 -0
  91. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/browser/browser.py +0 -0
  92. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/critical_exit/__init__.py +0 -0
  93. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/critical_exit/check_key_is_press.py +0 -0
  94. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/critical_exit/critical_exit.py +0 -0
  95. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/critical_exit/win32_vk.py +0 -0
  96. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/exception/__init__.py +0 -0
  97. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/exception/exception_tags.py +0 -0
  98. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/exception/exceptions.py +0 -0
  99. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/file/__init__.py +0 -0
  100. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/file/open/__init__.py +0 -0
  101. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/file/open/open_file.py +0 -0
  102. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/file/save/__init__.py +0 -0
  103. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/file/save/save_file.py +0 -0
  104. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/hotkey/__init__.py +0 -0
  105. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/hotkey/hotkey_service.py +0 -0
  106. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/json/__init__.py +0 -0
  107. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/json/json_file.py +0 -0
  108. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/json/json_repository.py +0 -0
  109. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/json_format/__init__.py +0 -0
  110. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/json_format/json_process.py +0 -0
  111. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/logging/__init__.py +0 -0
  112. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/logging/loggin_instance.py +0 -0
  113. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/multi_language/__init__.py +0 -0
  114. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/multi_language/france.py +0 -0
  115. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/multi_language/germany.py +0 -0
  116. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/multi_language/italy.py +0 -0
  117. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/multi_language/language_wrapper.py +0 -0
  118. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/multi_language/russian.py +0 -0
  119. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/multi_language/simplified_chinese.py +0 -0
  120. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/preset_schedule/__init__.py +0 -0
  121. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/preset_schedule/preset_schedule_service.py +0 -0
  122. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/redirect_manager/__init__.py +0 -0
  123. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/redirect_manager/redirect_manager_class.py +0 -0
  124. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/smart_pause/__init__.py +0 -0
  125. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/smart_pause/smart_pause_service.py +0 -0
  126. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/theme_schedule/__init__.py +0 -0
  127. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/theme_schedule/theme_schedule_service.py +0 -0
  128. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/utils/web_url.py +0 -0
  129. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/worker/__init__.py +0 -0
  130. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine/worker/qthread_worker.py +0 -0
  131. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine.egg-info/SOURCES.txt +0 -0
  132. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine.egg-info/dependency_links.txt +0 -0
  133. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine.egg-info/entry_points.txt +0 -0
  134. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine.egg-info/requires.txt +0 -0
  135. {frontengine-1.0.14 → frontengine-1.0.16}/frontengine.egg-info/top_level.txt +0 -0
  136. {frontengine-1.0.14 → frontengine-1.0.16}/setup.cfg +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: frontengine
3
- Version: 1.0.14
3
+ Version: 1.0.16
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
@@ -144,6 +144,30 @@ def windows_platforms(exclude_hwnds=()) -> list:
144
144
  return []
145
145
 
146
146
 
147
+ def idle_seconds():
148
+ """
149
+ 回傳使用者未操作的秒數;無法取得時回傳 None。僅 Windows 實作。
150
+ Seconds since the last user input, or None when unavailable (Windows only).
151
+ """
152
+ if sys.platform != "win32":
153
+ return None
154
+ try:
155
+ import ctypes
156
+
157
+ class _LASTINPUTINFO(ctypes.Structure):
158
+ _fields_ = [("cbSize", ctypes.c_uint), ("dwTime", ctypes.c_uint)]
159
+
160
+ info = _LASTINPUTINFO()
161
+ info.cbSize = ctypes.sizeof(info)
162
+ if not ctypes.windll.user32.GetLastInputInfo(ctypes.byref(info)):
163
+ return None
164
+ elapsed_ms = ctypes.windll.kernel32.GetTickCount() - info.dwTime
165
+ return max(0.0, elapsed_ms / 1000.0)
166
+ except Exception as error: # pragma: no cover - Win32 boundary
167
+ front_engine_logger.warning(f"[idle_seconds] error: {error!r}")
168
+ return None
169
+
170
+
147
171
  def pop_due_reminders(now, reminders):
148
172
  """
149
173
  依 now 分出已到期與未到期的提醒。reminders 為 (due_datetime, text) 清單。
@@ -266,6 +290,40 @@ class PetMood:
266
290
  return self.CONTENT
267
291
 
268
292
 
293
+ class PetHunger:
294
+ """
295
+ 寵物飽足值 0~100:餵食上升、隨時間下降;level() 回傳 full/ok/hungry。
296
+ Pet fullness 0..100: feeding raises it, time lowers it; level() buckets it.
297
+ """
298
+
299
+ FULL = "full"
300
+ OK = "ok"
301
+ HUNGRY = "hungry"
302
+
303
+ def __init__(self, value: int = 70) -> None:
304
+ self.value = self._clamp(value)
305
+
306
+ @staticmethod
307
+ def _clamp(value) -> int:
308
+ try:
309
+ return max(0, min(100, int(value)))
310
+ except (TypeError, ValueError):
311
+ return 70
312
+
313
+ def feed(self, amount: int = 30) -> None:
314
+ self.value = self._clamp(self.value + amount)
315
+
316
+ def decay(self, amount: int = 1) -> None:
317
+ self.value = self._clamp(self.value - amount)
318
+
319
+ def level(self) -> str:
320
+ if self.value >= 60:
321
+ return self.FULL
322
+ if self.value <= 25:
323
+ return self.HUNGRY
324
+ return self.OK
325
+
326
+
269
327
  class SpeechBubble(QWidget):
270
328
  """寵物頭上的小對話泡泡,數秒後自動消失 / A small speech bubble that auto-hides."""
271
329
 
@@ -612,6 +670,12 @@ class PetMotion:
612
670
  self._idle_count = 0
613
671
  self._new_state(force_walk=True)
614
672
 
673
+ def sleep(self) -> None:
674
+ """讓寵物進入睡眠(使用者閒置時呼叫)/ Put the pet to sleep."""
675
+ self.state = STATE_SLEEP
676
+ self._state_ticks = self._rng.randint(300, 600)
677
+ self.follow_target_x = None
678
+
615
679
  # --- free wander ---
616
680
  def _step_wander(self, left, top, right, bottom) -> Tuple[int, int]:
617
681
  if abs(self.vy) < 1e-9:
@@ -702,6 +766,8 @@ class DesktopPetWidget(BaseWidget):
702
766
  self._moved = False
703
767
  self._chatter_rng = _random_module.SystemRandom()
704
768
  self._mood = PetMood(user_setting_dict.get("pet_mood", 60))
769
+ self._hunger = PetHunger(user_setting_dict.get("pet_hunger", 70))
770
+ self._hunger_warned = False
705
771
  self._messages = self._load_messages()
706
772
  self._sound: Optional[QSoundEffect] = None
707
773
  self._init_sound(sound_path)
@@ -714,6 +780,9 @@ class DesktopPetWidget(BaseWidget):
714
780
  # 電量提醒 / Low-battery reaction
715
781
  self._battery_provider = read_battery
716
782
  self._battery_warned = False
783
+ # 閒置反應 / Idle reaction
784
+ self._idle_provider = idle_seconds
785
+ self._idle_reacted = False
717
786
  # 提醒事項 / Reminders
718
787
  self._now_provider = datetime.now
719
788
  self._reminders: list = []
@@ -728,6 +797,9 @@ class DesktopPetWidget(BaseWidget):
728
797
  self.clone_action = QAction(language_wrapper.language_word_dict.get("pet_clone", "Clone"), self)
729
798
  self.clone_action.triggered.connect(self.clone_requested.emit)
730
799
  self.menu.addAction(self.clone_action)
800
+ self.feed_action = QAction(language_wrapper.language_word_dict.get("pet_feed", "Feed"), self)
801
+ self.feed_action.triggered.connect(self.feed)
802
+ self.menu.addAction(self.feed_action)
731
803
  self.reminder_action = QAction(
732
804
  language_wrapper.language_word_dict.get("pet_set_reminder", "Set reminder..."), self)
733
805
  self.reminder_action.triggered.connect(self._prompt_reminder)
@@ -866,6 +938,9 @@ class DesktopPetWidget(BaseWidget):
866
938
  "sad": lines("pet_chatter_sad", "Feeling a bit lonely...|Pet me?|(._.)"),
867
939
  "meet": lines("pet_chatter_meet", "Hi friend!|Hello!|Let's play!"),
868
940
  "battery": lines("pet_chatter_battery", "Battery's low - plug me in?|Low power!|Find a charger?"),
941
+ "hungry": lines("pet_chatter_hungry", "I'm hungry...|Got a snack?|Feed me?"),
942
+ "fed": lines("pet_chatter_fed", "Yum!|Thank you!|Delicious!"),
943
+ "away": lines("pet_chatter_away", "Still there?|I'll nap till you're back~|Zzz..."),
869
944
  "any": lines("pet_chatter_any", "Hi there!|(^_^)|Keep going!"),
870
945
  }
871
946
 
@@ -930,11 +1005,64 @@ class DesktopPetWidget(BaseWidget):
930
1005
 
931
1006
  def _on_chatter(self) -> None:
932
1007
  self._mood.decay() # a little neglect over time
1008
+ self._hunger.decay()
933
1009
  self._persist_mood()
934
- if not self._warn_battery(): # a low-battery warning takes priority
1010
+ # priority: user idle (nap), low battery, hunger, otherwise normal chatter
1011
+ if not self._check_idle() and not self._warn_battery() and not self._warn_hungry():
935
1012
  self.say()
936
1013
  self._schedule_chatter()
937
1014
 
1015
+ IDLE_THRESHOLD = 120.0
1016
+
1017
+ def _check_idle(self) -> bool:
1018
+ """使用者閒置久了打盹並說一句;回來後醒。回傳是否有反應(抑制一般閒聊)。"""
1019
+ seconds = self._idle_provider()
1020
+ if seconds is None:
1021
+ return False
1022
+ if seconds >= self.IDLE_THRESHOLD:
1023
+ if not self._idle_reacted:
1024
+ self._idle_reacted = True
1025
+ self.motion.sleep()
1026
+ if self._talk:
1027
+ pool = self._messages.get("away") or []
1028
+ if pool:
1029
+ self.say(pool[self._chatter_rng.randrange(len(pool))])
1030
+ return True
1031
+ return False
1032
+ if seconds < 5.0 and self._idle_reacted:
1033
+ self._idle_reacted = False
1034
+ self.motion.wake()
1035
+ return False
1036
+
1037
+ def _persist_hunger(self) -> None:
1038
+ user_setting_dict["pet_hunger"] = self._hunger.value
1039
+
1040
+ def feed(self) -> None:
1041
+ """餵食:補足飽足並讓心情變好,說一句道謝。"""
1042
+ self._hunger.feed()
1043
+ self._mood.pet()
1044
+ self._persist_hunger()
1045
+ self._persist_mood()
1046
+ pool = self._messages.get("fed") or []
1047
+ if pool:
1048
+ self.say(pool[self._chatter_rng.randrange(len(pool))])
1049
+
1050
+ def _warn_hungry(self) -> bool:
1051
+ """飢餓時討食一次;吃飽後重置。回傳是否有討食。"""
1052
+ self._persist_hunger()
1053
+ if not self._talk:
1054
+ return False
1055
+ if self._hunger.level() == PetHunger.HUNGRY:
1056
+ if not self._hunger_warned:
1057
+ self._hunger_warned = True
1058
+ pool = self._messages.get("hungry") or []
1059
+ if pool:
1060
+ self.say(pool[self._chatter_rng.randrange(len(pool))])
1061
+ return True
1062
+ elif self._hunger.level() == PetHunger.FULL:
1063
+ self._hunger_warned = False
1064
+ return False
1065
+
938
1066
  BATTERY_THRESHOLD = 20
939
1067
 
940
1068
  def _warn_battery(self) -> bool:
@@ -36,6 +36,9 @@ user_setting_dict: Dict[str, Any] = {
36
36
  # 桌面寵物心情值(0~100),跨工作階段保存
37
37
  # Desktop pet mood (0..100), persisted across sessions
38
38
  "pet_mood": 60,
39
+ # 桌面寵物飽足值(0~100)
40
+ # Desktop pet fullness (0..100)
41
+ "pet_hunger": 70,
39
42
  }
40
43
 
41
44
 
@@ -225,6 +225,10 @@ english_word_dict = {
225
225
  "pet_behaviour_chase": "Chase cursor",
226
226
  "pet_climb_label": "Climb walls",
227
227
  "pet_clone": "Clone",
228
+ "pet_feed": "Feed",
229
+ "pet_chatter_hungry": "I'm hungry...|Got a snack?|Feed me, please?|My tummy's rumbling~",
230
+ "pet_chatter_fed": "Yum!|Thank you!|Delicious!|Nom nom (^o^)",
231
+ "pet_chatter_away": "Still there?|I'll nap till you're back~|Zzz...|Take your time!",
228
232
  "pet_set_reminder": "Set reminder...",
229
233
  "pet_reminder_prompt": "Remind me to:",
230
234
  "pet_reminder_minutes": "In how many minutes?",
@@ -226,6 +226,10 @@ traditional_chinese_word_dict = {
226
226
  "pet_behaviour_chase": "追逐游標",
227
227
  "pet_climb_label": "攀爬牆壁",
228
228
  "pet_clone": "複製",
229
+ "pet_feed": "餵食",
230
+ "pet_chatter_hungry": "我餓了…|有點心嗎?|餵餵我好嗎?|肚子咕咕叫~",
231
+ "pet_chatter_fed": "好吃!|謝謝你!|真美味!|嗯嗯 (^o^)",
232
+ "pet_chatter_away": "還在嗎?|我先打個盹等你回來~|Zzz…|慢慢來沒關係!",
229
233
  "pet_set_reminder": "設定提醒...",
230
234
  "pet_reminder_prompt": "提醒我:",
231
235
  "pet_reminder_minutes": "幾分鐘後?",
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: frontengine
3
- Version: 1.0.14
3
+ Version: 1.0.16
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
@@ -6,7 +6,7 @@ build-backend = "setuptools.build_meta"
6
6
 
7
7
  [project]
8
8
  name = "frontengine"
9
- version = "1.0.14"
9
+ version = "1.0.16"
10
10
  authors = [
11
11
  { name = "JE-Chen", email = "jechenmailman@gmail.com" },
12
12
  ]
File without changes
File without changes
File without changes