frontengine 1.0.41__tar.gz → 1.0.43__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.41 → frontengine-1.0.43}/PKG-INFO +1 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/monitor/monitor_widget.py +2 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/particle/particle_ui.py +13 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/pet/desktop_pet.py +83 -40
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/presentation/cursor_effects.py +1 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/dialog/choose_file_dialog.py +9 -3
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/dialog/window_pin_dialog.py +1 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/menu/preset_menu.py +6 -6
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/menu/settings_menu.py +1 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/control_center/control_center_ui.py +1 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/focus/focus_setting_ui.py +3 -3
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/image/image_setting_ui.py +1 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/pet/pet_setting_ui.py +49 -44
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/presentation/presentation_setting_ui.py +6 -6
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/scene_setting/scene_manager.py +49 -34
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/screen_care/screen_care_setting_ui.py +3 -3
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/sound_player/sound_player_setting_ui.py +9 -4
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/text/text_setting_ui.py +25 -40
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/utils.py +52 -3
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/wallpaper/wallpaper_setting_ui.py +42 -35
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/web/web_setting_ui.py +25 -29
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/widgets/widgets_setting_ui.py +7 -7
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/user_setting/preset_repository.py +56 -32
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/audio_meter/loopback_capture.py +1 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/audio_meter/system_audio_meter.py +10 -7
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/platform_info/platform_info.py +6 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/redirect_manager/redirect_manager_class.py +7 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/system_stats/system_stats.py +9 -3
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/web_url.py +33 -15
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/window_pin/window_pin.py +6 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine.egg-info/PKG-INFO +1 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/pyproject.toml +1 -1
- {frontengine-1.0.41 → frontengine-1.0.43}/LICENSE +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/README.md +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/__main__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/base_widget.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/camera/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/camera/camera_widget.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/capture/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/capture/region_capture.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/focus_shield/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/focus_shield/focus_shield_widget.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/gaming/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/gaming/crosshair_widget.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/gif/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/gif/paint_gif.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/image/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/image/paint_image.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/load/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/load/load_someone_make_ui.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/measure/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/measure/measure_widget.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/monitor/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/notes/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/notes/sticky_note_widget.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/overlay_factory.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/particle/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/pet/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/presentation/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/presentation/annotation_overlay.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/presentation/keystroke_display.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/presentation/magnifier.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/scene/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/scene/extend_graphic_scene.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/scene/extend_graphic_view.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/scene/scene.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/screen_care/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/screen_care/color_vision_widget.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/screen_care/screen_filter.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/sound_player/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/sound_player/sound_effect.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/sound_player/sound_player.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/spectrum/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/spectrum/spectrum_widget.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/teleprompter/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/teleprompter/teleprompter_widget.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/text/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/text/draw_text.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/toast/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/toast/toast_widget.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/video/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/video/video_player.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/wallpaper/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/wallpaper/wallpaper_widget.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/web/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/web/webview.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/show/window_helpers.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/system_tray/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/system_tray/extend_system_tray.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/color/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/color/global_color.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/dialog/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/dialog/app_profile_dialog.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/dialog/clipboard_dialog.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/dialog/hotkey_settings_dialog.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/dialog/reminder_dialog.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/dialog/save_file_dialog.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/dialog/screen_text_dialog.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/dialog/smart_pause_dialog.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/dialog/usage_report_dialog.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/main_ui.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/menu/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/menu/help_menu.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/menu/how_to_menu.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/menu/language_menu.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/control_center/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/focus/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/gif/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/gif/gif_setting_ui.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/image/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/particle/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/particle/particle_setting_ui.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/pet/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/presentation/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/scene_setting/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/scene_setting/scene_page/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/scene_setting/scene_page/base_scene_page.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/scene_setting/scene_page/gif.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/scene_setting/scene_page/image.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/scene_setting/scene_page/registry.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/scene_setting/scene_page/sound.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/scene_setting/scene_page/text.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/scene_setting/scene_page/video.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/scene_setting/scene_page/web.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/scene_setting/scene_setting_ui.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/screen_care/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/sound_player/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/stream/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/stream/stream_setting_ui.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/text/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/tools/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/tools/tools_setting_ui.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/video/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/video/video_setting_ui.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/wallpaper/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/web/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/widgets/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/user_setting/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/user_setting/scene_setting.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/user_setting/user_setting_file.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/app_profile/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/app_profile/app_profile_service.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/audio_meter/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/audio_meter/audio_envelope.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/audio_meter/screen_audio.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/audio_meter/spectrum_analyzer.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/autostart/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/autostart/autostart_service.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/break_reminder/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/break_reminder/break_reminder.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/browser/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/browser/browser.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/clipboard/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/clipboard/clipboard_history.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/clipboard/clipboard_watcher.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/color_vision/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/color_vision/color_vision.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/critical_exit/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/critical_exit/check_key_is_press.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/critical_exit/critical_exit.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/critical_exit/win32_vk.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/exception/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/exception/exception_tags.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/exception/exceptions.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/file/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/file/open/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/file/open/open_file.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/file/save/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/file/save/save_file.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/focus_shield/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/focus_shield/focus_shield.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/focus_timer/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/focus_timer/focus_timer.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/hotkey/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/hotkey/hotkey_service.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/input_watch/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/input_watch/input_watch_service.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/json/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/json/json_file.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/json/json_repository.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/json_format/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/json_format/json_process.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/logging/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/logging/loggin_instance.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/measure/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/measure/measure.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/multi_language/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/multi_language/english.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/multi_language/france.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/multi_language/germany.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/multi_language/italy.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/multi_language/language_wrapper.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/multi_language/russian.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/multi_language/simplified_chinese.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/multi_language/traditional_chinese.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/now_playing/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/now_playing/now_playing.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/obs/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/obs/obs_client.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/obs/obs_protocol.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/obs/websocket_frames.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/pet_chat/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/pet_chat/pet_chat_service.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/platform_info/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/playlist/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/playlist/playlist.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/plugins/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/plugins/plugin_loader.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/power_mode/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/power_mode/power_mode.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/preset_schedule/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/preset_schedule/preset_schedule_service.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/recording/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/recording/frame_recorder.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/recording/gif_writer.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/redirect_manager/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/reminder/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/reminder/reminder_service.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/screen_text/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/screen_text/screen_text_service.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/smart_pause/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/smart_pause/pause_rules.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/smart_pause/smart_pause_service.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/soundboard/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/soundboard/soundboard.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/system_stats/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/text_source/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/text_source/text_source.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/theme_schedule/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/theme_schedule/theme_schedule_service.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/usage_tracking/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/usage_tracking/usage_service.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/usage_tracking/usage_tracker.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/weather/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/weather/weather_service.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/window_pin/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/window_pin/window_layout.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/workshop/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/utils/workshop/workshop_content.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/worker/__init__.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine/worker/qthread_worker.py +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine.egg-info/SOURCES.txt +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine.egg-info/dependency_links.txt +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine.egg-info/entry_points.txt +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine.egg-info/requires.txt +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/frontengine.egg-info/top_level.txt +0 -0
- {frontengine-1.0.41 → frontengine-1.0.43}/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.43
|
|
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
|
|
@@ -92,7 +92,8 @@ class SystemMonitorWidget(BaseWidget):
|
|
|
92
92
|
self._series: Dict[str, Deque[float]] = {
|
|
93
93
|
key: deque(maxlen=self.history_length) for key, _label, _color in LINES
|
|
94
94
|
}
|
|
95
|
-
self._latest: Dict[str, float] =
|
|
95
|
+
self._latest: Dict[str, float] = dict.fromkeys(
|
|
96
|
+
(key for key, _label, _color in LINES), 0.0)
|
|
96
97
|
self._font = QFont()
|
|
97
98
|
self._font.setPointSize(9)
|
|
98
99
|
self._timer = QTimer(self)
|
|
@@ -1,7 +1,19 @@
|
|
|
1
1
|
import random
|
|
2
2
|
import sys
|
|
3
3
|
|
|
4
|
-
|
|
4
|
+
# 明確列出用到的 OpenGL 名稱。星號匯入會讓靜態檢查完全看不出哪些名字存在,
|
|
5
|
+
# 也就是說整個檔案的「未定義名稱」檢查等於失效。
|
|
6
|
+
# The OpenGL names this file uses, spelled out. A star import blinds static
|
|
7
|
+
# analysis to what exists, which switches off undefined-name checking for the
|
|
8
|
+
# whole file.
|
|
9
|
+
from OpenGL.GL import (
|
|
10
|
+
GL_BLEND, GL_COLOR_BUFFER_BIT, GL_CULL_FACE, GL_DEPTH_BUFFER_BIT, GL_DEPTH_TEST,
|
|
11
|
+
GL_LINEAR, GL_MODELVIEW, GL_ONE_MINUS_SRC_ALPHA, GL_PROJECTION, GL_QUADS, GL_RGBA,
|
|
12
|
+
GL_SRC_ALPHA, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_TEXTURE_MIN_FILTER,
|
|
13
|
+
GL_UNSIGNED_BYTE, glBegin, glBindTexture, glBlendFunc, glClear, glClearColor, glColor4f,
|
|
14
|
+
glDisable, glEnable, glEnd, glGenTextures, glLoadIdentity, glMatrixMode, glOrtho,
|
|
15
|
+
glTexCoord2f, glTexImage2D, glTexParameteri, glTranslatef, glVertex2f, glViewport,
|
|
16
|
+
)
|
|
5
17
|
from PySide6.QtCore import Qt, QTimer
|
|
6
18
|
from PySide6.QtGui import QSurfaceFormat, QPixmap
|
|
7
19
|
from PySide6.QtOpenGLWidgets import QOpenGLWidget
|
|
@@ -92,6 +92,12 @@ def scan_pet_pack(folder: str) -> dict:
|
|
|
92
92
|
|
|
93
93
|
# 可以請寵物幫忙開啟的網址協定 / URL schemes the pet will open for you
|
|
94
94
|
_WEB_SCHEMES = frozenset({"http", "https"})
|
|
95
|
+
# 可以當寵物音效的副檔名。音效路徑可能來自匯入的預設集或 Workshop 內容,
|
|
96
|
+
# 所以只認這幾種副檔名的既存檔案。
|
|
97
|
+
# The suffixes accepted as a pet sound. The path can arrive from an imported
|
|
98
|
+
# preset or Workshop content, so only an existing file with one of these is
|
|
99
|
+
# honoured.
|
|
100
|
+
_SOUND_SUFFIXES = (".wav", ".mp3", ".ogg", ".m4a", ".flac")
|
|
95
101
|
|
|
96
102
|
|
|
97
103
|
# 拖進寵物的檔案分類 / What a file dropped onto the pet means
|
|
@@ -99,6 +105,28 @@ DROP_SPRITE = "sprite" # 圖片或動作包 -> 換一套外觀
|
|
|
99
105
|
DROP_FOOD = "food" # 其他檔案 -> 當成食物餵給寵物
|
|
100
106
|
|
|
101
107
|
|
|
108
|
+
def acceptable_sound(sound_path) -> Optional[Path]:
|
|
109
|
+
"""
|
|
110
|
+
可以拿來當寵物音效的路徑,否則回傳 None。音效路徑可能來自匯入的預設集或
|
|
111
|
+
Workshop 內容(別人寫的資料),所以只接受「確實存在、副檔名是音訊」的檔案
|
|
112
|
+
——不讓一份預設集指使程式去開任意檔案。
|
|
113
|
+
The path to use as a pet sound, or None. It can arrive from an imported
|
|
114
|
+
preset or from Workshop content - data someone else wrote - so only a file
|
|
115
|
+
that actually exists and carries an audio suffix is accepted: a preset does
|
|
116
|
+
not get to point this at any file it likes.
|
|
117
|
+
"""
|
|
118
|
+
if not sound_path:
|
|
119
|
+
return None
|
|
120
|
+
# 下一行就是這個函式存在的理由:把外部給的字串收斂成「確定存在的音訊檔」,
|
|
121
|
+
# 不符合就回 None。
|
|
122
|
+
# The next line is why this function exists: narrow an outside string down
|
|
123
|
+
# to an audio file that actually exists, and return None otherwise.
|
|
124
|
+
path = Path(str(sound_path)) # NOSONAR - validated on the very next line
|
|
125
|
+
if path.is_file() and path.suffix.lower() in _SOUND_SUFFIXES:
|
|
126
|
+
return path
|
|
127
|
+
return None
|
|
128
|
+
|
|
129
|
+
|
|
102
130
|
def classify_drop(path) -> Optional[str]:
|
|
103
131
|
"""
|
|
104
132
|
判斷拖到寵物身上的檔案要換裝還是當食物;路徑無效或空資料夾回傳 None。
|
|
@@ -238,7 +266,7 @@ class PetTimeline:
|
|
|
238
266
|
"""
|
|
239
267
|
|
|
240
268
|
def __init__(self, events) -> None:
|
|
241
|
-
self._events = sorted(
|
|
269
|
+
self._events = sorted(events, key=lambda item: item[0])
|
|
242
270
|
self._index = 0
|
|
243
271
|
|
|
244
272
|
def __len__(self) -> int:
|
|
@@ -319,12 +347,13 @@ class PetTagGame:
|
|
|
319
347
|
tick from outside.
|
|
320
348
|
"""
|
|
321
349
|
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
350
|
+
DEFAULT_CATCH_DISTANCE = 60.0
|
|
351
|
+
DEFAULT_FLEE_DISTANCE = 220.0
|
|
352
|
+
DEFAULT_COOLDOWN_TICKS = 20
|
|
325
353
|
|
|
326
|
-
def __init__(self, catch_distance: float =
|
|
327
|
-
|
|
354
|
+
def __init__(self, catch_distance: float = DEFAULT_CATCH_DISTANCE,
|
|
355
|
+
flee_distance: float = DEFAULT_FLEE_DISTANCE,
|
|
356
|
+
cooldown_ticks: int = DEFAULT_COOLDOWN_TICKS) -> None:
|
|
328
357
|
self.catch_distance = float(catch_distance)
|
|
329
358
|
self.flee_distance = float(flee_distance)
|
|
330
359
|
self.cooldown_ticks = max(0, int(cooldown_ticks))
|
|
@@ -361,7 +390,7 @@ class PetTagGame:
|
|
|
361
390
|
self.reset()
|
|
362
391
|
return {}
|
|
363
392
|
if self.it not in positions:
|
|
364
|
-
self.it =
|
|
393
|
+
self.it = min(positions)
|
|
365
394
|
self._cooldown = self.cooldown_ticks
|
|
366
395
|
# 冷卻期間只是跑給對方追,不換鬼;先判斷再遞減,冷卻 N 拍就真的保護 N 拍。
|
|
367
396
|
# While cooling down nobody can be tagged; check before decrementing so a
|
|
@@ -801,7 +830,7 @@ class PetMotion:
|
|
|
801
830
|
self.vx = -abs(self.vx)
|
|
802
831
|
return int(self.x), int(self.y)
|
|
803
832
|
|
|
804
|
-
def _step_fall(self, left, top, right, bottom,
|
|
833
|
+
def _step_fall(self, left, top, right, bottom, _floor_y) -> Tuple[int, int]:
|
|
805
834
|
"""落下:撞牆/天花板反彈,並在越過視窗平台或螢幕地板時落地。"""
|
|
806
835
|
prev_feet = self.y + self.height
|
|
807
836
|
self.vy += self.GRAVITY
|
|
@@ -816,36 +845,48 @@ class PetMotion:
|
|
|
816
845
|
if self.y <= top:
|
|
817
846
|
self.y = float(top)
|
|
818
847
|
self.vy = abs(self.vy) * self.WALL_DAMPING
|
|
819
|
-
|
|
820
|
-
|
|
848
|
+
land_feet, land_span = self._landing_for(prev_feet, self.y + self.height, bottom)
|
|
849
|
+
if land_feet is not None:
|
|
850
|
+
self._land_on(land_feet, land_span)
|
|
851
|
+
return int(self.x), int(self.y)
|
|
821
852
|
|
|
853
|
+
def _landing_for(self, prev_feet: float, new_feet: float, bottom: float):
|
|
854
|
+
"""
|
|
855
|
+
這一步跨過了哪個落腳處:回傳 (腳底高度, 平台範圍)。平台優先於螢幕地板,
|
|
856
|
+
多個平台則取最高的那個;都沒跨過就回傳 (None, None)。
|
|
857
|
+
What this step crossed, as (feet height, platform span). A platform wins
|
|
858
|
+
over the screen floor, the highest platform wins among several, and
|
|
859
|
+
crossing nothing gives (None, None).
|
|
860
|
+
"""
|
|
861
|
+
center_x = self.x + self.width / 2.0
|
|
822
862
|
land_feet = None
|
|
823
863
|
land_span = None
|
|
824
864
|
for platform_left, platform_right, platform_y in self.platforms:
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
865
|
+
crossed = prev_feet <= platform_y <= new_feet
|
|
866
|
+
over_it = platform_left <= center_x <= platform_right
|
|
867
|
+
if crossed and over_it and (land_feet is None or platform_y < land_feet):
|
|
868
|
+
land_feet = float(platform_y)
|
|
869
|
+
land_span = (float(platform_left), float(platform_right))
|
|
829
870
|
if prev_feet <= bottom <= new_feet and (land_feet is None or bottom < land_feet):
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
|
|
841
|
-
|
|
842
|
-
|
|
843
|
-
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
|
|
871
|
+
return (float(bottom), None)
|
|
872
|
+
return (land_feet, land_span)
|
|
873
|
+
|
|
874
|
+
def _land_on(self, land_feet: float, land_span) -> None:
|
|
875
|
+
"""落地:還有力氣就彈起來,否則就站定並恢復走動。"""
|
|
876
|
+
self.y = float(land_feet - self.height)
|
|
877
|
+
if abs(self.vy) > self.BOUNCE_THRESHOLD:
|
|
878
|
+
self.vy = -self.vy * self.BOUNCE_DAMPING
|
|
879
|
+
return
|
|
880
|
+
self.vy = 0.0
|
|
881
|
+
self._airborne = False
|
|
882
|
+
self.surface = SURFACE_FLOOR
|
|
883
|
+
self.on_platform = land_span is not None
|
|
884
|
+
self.platform_span = land_span
|
|
885
|
+
self.ground_feet = land_feet
|
|
886
|
+
self.vx = float(self.speed) if self.vx >= 0 else float(-self.speed)
|
|
887
|
+
self._new_state(force_walk=True)
|
|
847
888
|
|
|
848
|
-
def _step_follow(self, left,
|
|
889
|
+
def _step_follow(self, left, _top, right, _bottom, floor_y) -> Tuple[int, int]:
|
|
849
890
|
"""朝 follow_target_x 走過去;抵達附近即清除並恢復隨機行為。"""
|
|
850
891
|
center_x = self.x + self.width / 2.0
|
|
851
892
|
if abs(center_x - self.follow_target_x) <= self.speed + 2.0:
|
|
@@ -898,7 +939,7 @@ class PetMotion:
|
|
|
898
939
|
self.vx = -abs(self.vx)
|
|
899
940
|
return int(self.x), int(self.y)
|
|
900
941
|
|
|
901
|
-
def _step_climb(self, left, top, right,
|
|
942
|
+
def _step_climb(self, left, top, right, _bottom, floor_y) -> Tuple[int, int]:
|
|
902
943
|
"""沿螢幕邊緣爬行;隨機放手則掉落 / Crawl the screen perimeter; may let go and fall."""
|
|
903
944
|
if self._rng.random() < self.DROP_CHANCE:
|
|
904
945
|
self.surface = SURFACE_FLOOR
|
|
@@ -1348,7 +1389,7 @@ class DesktopPetWidget(BaseWidget):
|
|
|
1348
1389
|
|
|
1349
1390
|
def start_moving(self, bounds: Tuple[int, int, int, int], interval_ms: int = 33) -> None:
|
|
1350
1391
|
front_engine_logger.info(f"[DesktopPetWidget] start_moving | bounds={bounds}")
|
|
1351
|
-
left,
|
|
1392
|
+
left, _top, _right, bottom = bounds
|
|
1352
1393
|
self.motion.set_bounds(bounds)
|
|
1353
1394
|
self.motion.x = float(left)
|
|
1354
1395
|
self.motion.y = float(bottom - self.pet_size)
|
|
@@ -1596,10 +1637,12 @@ class DesktopPetWidget(BaseWidget):
|
|
|
1596
1637
|
self._pending_chat_reply = None
|
|
1597
1638
|
|
|
1598
1639
|
def _init_sound(self, sound_path: Optional[str]) -> None:
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
path
|
|
1602
|
-
|
|
1640
|
+
"""載入寵物音效(路徑先經過 acceptable_sound 檢查)。"""
|
|
1641
|
+
path = acceptable_sound(sound_path)
|
|
1642
|
+
if path is None:
|
|
1643
|
+
if sound_path:
|
|
1644
|
+
front_engine_logger.warning(
|
|
1645
|
+
f"[DesktopPetWidget] refusing sound path: {sound_path!r}")
|
|
1603
1646
|
return
|
|
1604
1647
|
try:
|
|
1605
1648
|
self._sound = QSoundEffect(self)
|
|
@@ -1829,8 +1872,8 @@ class DesktopPetWidget(BaseWidget):
|
|
|
1829
1872
|
event.acceptProposedAction()
|
|
1830
1873
|
|
|
1831
1874
|
def dragMoveEvent(self, event) -> None:
|
|
1832
|
-
|
|
1833
|
-
|
|
1875
|
+
"""拖曳過程中的判斷和進入時完全一樣,直接沿用同一套規則。"""
|
|
1876
|
+
self.dragEnterEvent(event)
|
|
1834
1877
|
|
|
1835
1878
|
def dropEvent(self, event) -> None:
|
|
1836
1879
|
path = self.dropped_path(event.mimeData())
|
|
@@ -121,7 +121,7 @@ class CursorEffectWidget(BaseWidget):
|
|
|
121
121
|
except Exception: # pragma: no cover - defensive around injected providers
|
|
122
122
|
return
|
|
123
123
|
self.cursor_point = QPoint(int(position.x()) - self.x(), int(position.y()) - self.y())
|
|
124
|
-
for ripple in
|
|
124
|
+
for ripple in self.ripples[:]:
|
|
125
125
|
ripple["step"] += 1
|
|
126
126
|
if ripple["step"] > RIPPLE_STEPS:
|
|
127
127
|
self.ripples.remove(ripple)
|
|
@@ -7,6 +7,12 @@ from frontengine.utils.logging.loggin_instance import front_engine_logger
|
|
|
7
7
|
from frontengine.utils.multi_language.language_wrapper import language_wrapper
|
|
8
8
|
|
|
9
9
|
|
|
10
|
+
# 動圖副檔名在多個選擇器裡重複出現
|
|
11
|
+
# The animation suffixes repeat across several pickers.
|
|
12
|
+
_GIF = ".gif"
|
|
13
|
+
_WEBP = ".webp"
|
|
14
|
+
|
|
15
|
+
|
|
10
16
|
def choose_file(
|
|
11
17
|
trigger_ui: QWidget,
|
|
12
18
|
file_filter: str,
|
|
@@ -50,7 +56,7 @@ def choose_gif(trigger_ui: QWidget) -> Optional[str]:
|
|
|
50
56
|
return choose_file(
|
|
51
57
|
trigger_ui,
|
|
52
58
|
file_filter="GIF WEBP (*.gif;*.webp)",
|
|
53
|
-
extensions=[
|
|
59
|
+
extensions=[_GIF, _WEBP],
|
|
54
60
|
warning_message=language_wrapper.language_word_dict.get("gif_setting_message_box")
|
|
55
61
|
)
|
|
56
62
|
|
|
@@ -60,7 +66,7 @@ def choose_image(trigger_ui: QWidget) -> Optional[str]:
|
|
|
60
66
|
return choose_file(
|
|
61
67
|
trigger_ui,
|
|
62
68
|
file_filter="Images (*.png;*.jpg;*.webp)",
|
|
63
|
-
extensions=[".png", ".jpg",
|
|
69
|
+
extensions=[".png", ".jpg", _WEBP],
|
|
64
70
|
warning_message=language_wrapper.language_word_dict.get("image_setting_message_box")
|
|
65
71
|
)
|
|
66
72
|
|
|
@@ -90,7 +96,7 @@ def choose_pet(trigger_ui: QWidget) -> Optional[str]:
|
|
|
90
96
|
return choose_file(
|
|
91
97
|
trigger_ui,
|
|
92
98
|
file_filter="Pet sprite (*.gif;*.webp;*.png;*.jpg)",
|
|
93
|
-
extensions=[
|
|
99
|
+
extensions=[_GIF, _WEBP, ".png", ".jpg"],
|
|
94
100
|
warning_message=language_wrapper.language_word_dict.get("gif_setting_message_box")
|
|
95
101
|
)
|
|
96
102
|
|
|
@@ -119,7 +119,7 @@ class WindowPinDialog(QDialog):
|
|
|
119
119
|
Release everything this dialog pinned and make it opaque again, so no
|
|
120
120
|
other program is left stuck on top or faded after FrontEngine exits.
|
|
121
121
|
"""
|
|
122
|
-
for handle in
|
|
122
|
+
for handle in self.pinned[:]:
|
|
123
123
|
window_pin.set_always_on_top(handle, False)
|
|
124
124
|
window_pin.set_opacity(handle, window_pin.MAX_OPACITY_PERCENT)
|
|
125
125
|
self.pinned.clear()
|
|
@@ -113,7 +113,7 @@ def _load_action(ui: "FrontEngineMainUI") -> Callable[[], None]:
|
|
|
113
113
|
return
|
|
114
114
|
try:
|
|
115
115
|
data = PresetRepository().load(preset)
|
|
116
|
-
except (OSError,
|
|
116
|
+
except (OSError, ValueError) as error:
|
|
117
117
|
QMessageBox.warning(ui, title, str(error))
|
|
118
118
|
return
|
|
119
119
|
_apply_state(ui, data)
|
|
@@ -158,7 +158,7 @@ def _export_action(ui: "FrontEngineMainUI") -> Callable[[], None]:
|
|
|
158
158
|
return
|
|
159
159
|
try:
|
|
160
160
|
PresetRepository().export_preset(preset, Path(destination))
|
|
161
|
-
except (OSError,
|
|
161
|
+
except (OSError, ValueError) as error:
|
|
162
162
|
QMessageBox.warning(ui, title, str(error))
|
|
163
163
|
return
|
|
164
164
|
QMessageBox.information(ui, title, _t("preset_exported", "Preset exported."))
|
|
@@ -177,7 +177,7 @@ def _import_action(ui: "FrontEngineMainUI") -> Callable[[], None]:
|
|
|
177
177
|
return
|
|
178
178
|
try:
|
|
179
179
|
PresetRepository().import_preset(Path(source))
|
|
180
|
-
except (OSError,
|
|
180
|
+
except (OSError, ValueError) as error:
|
|
181
181
|
QMessageBox.warning(ui, title, str(error))
|
|
182
182
|
return
|
|
183
183
|
QMessageBox.information(ui, title, _t("preset_imported", "Preset imported."))
|
|
@@ -221,7 +221,7 @@ def apply_named_preset(ui: "FrontEngineMainUI", name: str) -> bool:
|
|
|
221
221
|
front_engine_logger.info(f"[PresetMenu] apply_named_preset | name={name}")
|
|
222
222
|
try:
|
|
223
223
|
data = PresetRepository().load(name)
|
|
224
|
-
except (OSError,
|
|
224
|
+
except (OSError, ValueError) as error:
|
|
225
225
|
front_engine_logger.warning(f"[PresetMenu] preset '{name}' failed: {error!r}")
|
|
226
226
|
return False
|
|
227
227
|
_apply_state(ui, data)
|
|
@@ -272,7 +272,7 @@ def _export_package_action(ui: "FrontEngineMainUI") -> Callable[[], None]:
|
|
|
272
272
|
return
|
|
273
273
|
try:
|
|
274
274
|
PresetRepository().export_package(preset, Path(destination))
|
|
275
|
-
except (OSError,
|
|
275
|
+
except (OSError, ValueError) as error:
|
|
276
276
|
QMessageBox.warning(ui, title, str(error))
|
|
277
277
|
return
|
|
278
278
|
QMessageBox.information(ui, title, _t("preset_exported", "Preset exported."))
|
|
@@ -291,7 +291,7 @@ def _import_package_action(ui: "FrontEngineMainUI") -> Callable[[], None]:
|
|
|
291
291
|
return
|
|
292
292
|
try:
|
|
293
293
|
PresetRepository().import_package(Path(source))
|
|
294
|
-
except (OSError,
|
|
294
|
+
except (OSError, ValueError) as error:
|
|
295
295
|
QMessageBox.warning(ui, title, str(error))
|
|
296
296
|
return
|
|
297
297
|
QMessageBox.information(ui, title, _t("preset_imported", "Preset imported."))
|
|
@@ -233,7 +233,7 @@ def _import_settings(ui: "FrontEngineMainUI") -> None:
|
|
|
233
233
|
return
|
|
234
234
|
try:
|
|
235
235
|
import_user_setting(Path(source))
|
|
236
|
-
except (OSError,
|
|
236
|
+
except (OSError, ValueError) as error:
|
|
237
237
|
QMessageBox.warning(ui, title, str(error))
|
|
238
238
|
return
|
|
239
239
|
# Hotkeys can be re-applied live; language/theme need a restart.
|
{frontengine-1.0.41 → frontengine-1.0.43}/frontengine/ui/page/control_center/control_center_ui.py
RENAMED
|
@@ -240,7 +240,7 @@ class ControlCenterUI(QWidget):
|
|
|
240
240
|
guarded and the dead reference is pruned so one cannot crash the batch.
|
|
241
241
|
"""
|
|
242
242
|
for widget_list in self._all_overlay_widget_lists():
|
|
243
|
-
for widget in
|
|
243
|
+
for widget in widget_list[:]:
|
|
244
244
|
try:
|
|
245
245
|
action(widget)
|
|
246
246
|
except RuntimeError:
|
|
@@ -100,7 +100,7 @@ class FocusSettingUI(QWidget):
|
|
|
100
100
|
|
|
101
101
|
@staticmethod
|
|
102
102
|
def _close_all(widgets: list) -> None:
|
|
103
|
-
for widget in
|
|
103
|
+
for widget in widgets[:]:
|
|
104
104
|
try:
|
|
105
105
|
widget.close()
|
|
106
106
|
except RuntimeError:
|
|
@@ -136,7 +136,7 @@ class FocusSettingUI(QWidget):
|
|
|
136
136
|
language_wrapper.language_word_dict.get("focus_dim_start", "Dim the background"))
|
|
137
137
|
|
|
138
138
|
def _apply_dim_settings(self) -> None:
|
|
139
|
-
for widget in
|
|
139
|
+
for widget in self.dim_widget_list[:]:
|
|
140
140
|
try:
|
|
141
141
|
widget.set_dim(self.dim_slider.value())
|
|
142
142
|
except RuntimeError:
|
|
@@ -179,7 +179,7 @@ class FocusSettingUI(QWidget):
|
|
|
179
179
|
return
|
|
180
180
|
geometry = screen.geometry()
|
|
181
181
|
bounds = (geometry.x(), geometry.y(), geometry.width(), geometry.height())
|
|
182
|
-
for widget in
|
|
182
|
+
for widget in self.mask_widget_list[:]:
|
|
183
183
|
try:
|
|
184
184
|
widget.set_region(self.mask_region_combobox.currentData(),
|
|
185
185
|
self.mask_percent_slider.value())
|
|
@@ -208,7 +208,7 @@ class ImageSettingUI(QWidget):
|
|
|
208
208
|
return
|
|
209
209
|
self._slideshow_index = (self._slideshow_index + 1) % len(self._slideshow_paths)
|
|
210
210
|
next_path = self._slideshow_paths[self._slideshow_index]
|
|
211
|
-
for widget in
|
|
211
|
+
for widget in self.image_widget_list[:]:
|
|
212
212
|
setter = getattr(widget, "set_image_path", None)
|
|
213
213
|
if setter is None:
|
|
214
214
|
continue
|
|
@@ -11,6 +11,9 @@ from frontengine.show.pet.desktop_pet import (
|
|
|
11
11
|
)
|
|
12
12
|
from frontengine.ui.dialog.choose_file_dialog import choose_pet, choose_wav_sound
|
|
13
13
|
from frontengine.ui.page.utils import (
|
|
14
|
+
apply_checkbox_state,
|
|
15
|
+
apply_combobox_data_state,
|
|
16
|
+
apply_combobox_text_state,
|
|
14
17
|
build_recent_combobox,
|
|
15
18
|
build_target_monitor_combobox,
|
|
16
19
|
enable_file_drop,
|
|
@@ -29,6 +32,12 @@ from frontengine.utils.multi_language.language_wrapper import language_wrapper
|
|
|
29
32
|
_PET_EXTENSIONS = (".gif", ".webp", ".png", ".jpg")
|
|
30
33
|
|
|
31
34
|
|
|
35
|
+
# 多處共用的英文備援字串(只有在翻譯缺漏時才會看到)
|
|
36
|
+
# The English fallback shared by several call sites, seen only when a
|
|
37
|
+
# translation is missing.
|
|
38
|
+
_CHOOSE_PACK = "Choose pet pack..."
|
|
39
|
+
|
|
40
|
+
|
|
32
41
|
class PetSettingUI(QWidget):
|
|
33
42
|
def __init__(self):
|
|
34
43
|
front_engine_logger.info("[PetSettingUI] Init")
|
|
@@ -61,7 +70,7 @@ class PetSettingUI(QWidget):
|
|
|
61
70
|
)
|
|
62
71
|
self.choose_file_button.clicked.connect(self.choose_and_play)
|
|
63
72
|
self.choose_pack_button = QPushButton(
|
|
64
|
-
language_wrapper.language_word_dict.get("pet_choose_pack",
|
|
73
|
+
language_wrapper.language_word_dict.get("pet_choose_pack", _CHOOSE_PACK)
|
|
65
74
|
)
|
|
66
75
|
self.choose_pack_button.clicked.connect(self.choose_pack)
|
|
67
76
|
self.choose_sound_button = QPushButton(
|
|
@@ -294,7 +303,7 @@ class PetSettingUI(QWidget):
|
|
|
294
303
|
def _alive_pets(self) -> list:
|
|
295
304
|
"""回傳仍存活的寵物,並把已被銷毀者從清單移除。"""
|
|
296
305
|
alive = []
|
|
297
|
-
for pet in
|
|
306
|
+
for pet in self.pet_list[:]:
|
|
298
307
|
try:
|
|
299
308
|
pet.center()
|
|
300
309
|
except RuntimeError:
|
|
@@ -376,14 +385,14 @@ class PetSettingUI(QWidget):
|
|
|
376
385
|
"""選擇動作包資料夾(依 walk/idle/climb/fall/drag 檔名對應狀態)。"""
|
|
377
386
|
front_engine_logger.info("[PetSettingUI] choose_pack")
|
|
378
387
|
folder = QFileDialog.getExistingDirectory(
|
|
379
|
-
self, language_wrapper.language_word_dict.get("pet_choose_pack",
|
|
388
|
+
self, language_wrapper.language_word_dict.get("pet_choose_pack", _CHOOSE_PACK)
|
|
380
389
|
)
|
|
381
390
|
if not folder:
|
|
382
391
|
return
|
|
383
392
|
if not scan_pet_pack(folder):
|
|
384
393
|
QMessageBox.warning(
|
|
385
394
|
self,
|
|
386
|
-
language_wrapper.language_word_dict.get("pet_choose_pack",
|
|
395
|
+
language_wrapper.language_word_dict.get("pet_choose_pack", _CHOOSE_PACK),
|
|
387
396
|
language_wrapper.language_word_dict.get(
|
|
388
397
|
"pet_pack_empty", "No sprites (walk/idle/climb/fall/drag) found in that folder."),
|
|
389
398
|
)
|
|
@@ -432,49 +441,45 @@ class PetSettingUI(QWidget):
|
|
|
432
441
|
}
|
|
433
442
|
|
|
434
443
|
def set_state(self, state: dict) -> None:
|
|
444
|
+
"""把預設集的內容還原到這一頁的控制項上。"""
|
|
445
|
+
self._restore_media(state)
|
|
446
|
+
apply_combobox_data_state(self.behaviour_combobox, self._behaviour_from(state))
|
|
447
|
+
apply_combobox_text_state(state, (
|
|
448
|
+
(self.size_combobox, "size"),
|
|
449
|
+
(self.speed_combobox, "speed"),
|
|
450
|
+
(self.target_monitor_combobox, "target_monitor"),
|
|
451
|
+
(self.volume_combobox, "volume"),
|
|
452
|
+
(self.focus_minutes_combobox, "focus_minutes"),
|
|
453
|
+
(self.break_minutes_combobox, "break_minutes"),
|
|
454
|
+
))
|
|
455
|
+
apply_checkbox_state(state, (
|
|
456
|
+
(self.climb_checkbox, "climb"),
|
|
457
|
+
(self.talk_checkbox, "talk"),
|
|
458
|
+
(self.sit_checkbox, "sit"),
|
|
459
|
+
(self.audio_react_checkbox, "audio_react"),
|
|
460
|
+
(self.tag_checkbox, "tag"),
|
|
461
|
+
(self.speech_checkbox, "speech"),
|
|
462
|
+
(self.chat_checkbox, "chat"),
|
|
463
|
+
))
|
|
464
|
+
|
|
465
|
+
def _restore_media(self, state: dict) -> None:
|
|
466
|
+
"""還原圖片與音效的路徑(有圖才算準備好可以放)。"""
|
|
435
467
|
if state.get("pet_image_path"):
|
|
436
468
|
self.pet_image_path = state["pet_image_path"]
|
|
437
469
|
self.ready_to_play = True
|
|
438
470
|
self.ready_label.setText(language_wrapper.language_word_dict.get("Ready"))
|
|
439
|
-
for combobox, key in ((self.size_combobox, "size"), (self.speed_combobox, "speed")):
|
|
440
|
-
if state.get(key) is not None:
|
|
441
|
-
index = combobox.findText(str(state[key]))
|
|
442
|
-
if index >= 0:
|
|
443
|
-
combobox.setCurrentIndex(index)
|
|
444
|
-
behaviour = state.get("behaviour")
|
|
445
|
-
if behaviour is None and "gravity" in state: # back-compat with old presets
|
|
446
|
-
behaviour = BEHAVIOUR_FLOOR if state.get("gravity") else BEHAVIOUR_WANDER
|
|
447
|
-
if behaviour is not None:
|
|
448
|
-
index = self.behaviour_combobox.findData(behaviour)
|
|
449
|
-
if index >= 0:
|
|
450
|
-
self.behaviour_combobox.setCurrentIndex(index)
|
|
451
|
-
if "climb" in state:
|
|
452
|
-
self.climb_checkbox.setChecked(bool(state["climb"]))
|
|
453
|
-
if "talk" in state:
|
|
454
|
-
self.talk_checkbox.setChecked(bool(state["talk"]))
|
|
455
471
|
if state.get("sound"):
|
|
456
472
|
self.pet_sound_path = str(state["sound"])
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
if "
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
self.tag_checkbox.setChecked(bool(state["tag"]))
|
|
471
|
-
if "speech" in state:
|
|
472
|
-
self.speech_checkbox.setChecked(bool(state["speech"]))
|
|
473
|
-
if "chat" in state:
|
|
474
|
-
self.chat_checkbox.setChecked(bool(state["chat"]))
|
|
475
|
-
for combobox, key in ((self.focus_minutes_combobox, "focus_minutes"),
|
|
476
|
-
(self.break_minutes_combobox, "break_minutes")):
|
|
477
|
-
if state.get(key) is not None:
|
|
478
|
-
index = combobox.findText(str(state[key]))
|
|
479
|
-
if index >= 0:
|
|
480
|
-
combobox.setCurrentIndex(index)
|
|
473
|
+
|
|
474
|
+
@staticmethod
|
|
475
|
+
def _behaviour_from(state: dict):
|
|
476
|
+
"""
|
|
477
|
+
取出行為模式。舊的預設集只存了 gravity 布林值,這裡把它翻譯成對應的
|
|
478
|
+
行為,免得舊檔案還原後寵物不會動。
|
|
479
|
+
The behaviour to use. Older presets only stored a `gravity` flag, so it
|
|
480
|
+
is translated here rather than leaving an old file with no behaviour.
|
|
481
|
+
"""
|
|
482
|
+
behaviour = state.get("behaviour")
|
|
483
|
+
if behaviour is None and "gravity" in state:
|
|
484
|
+
behaviour = BEHAVIOUR_FLOOR if state.get("gravity") else BEHAVIOUR_WANDER
|
|
485
|
+
return behaviour
|
|
@@ -158,7 +158,7 @@ class PresentationSettingUI(QWidget):
|
|
|
158
158
|
|
|
159
159
|
@staticmethod
|
|
160
160
|
def _close_all(widgets: list) -> None:
|
|
161
|
-
for widget in
|
|
161
|
+
for widget in widgets[:]:
|
|
162
162
|
try:
|
|
163
163
|
widget.close()
|
|
164
164
|
except RuntimeError:
|
|
@@ -207,7 +207,7 @@ class PresentationSettingUI(QWidget):
|
|
|
207
207
|
widget.clear()
|
|
208
208
|
|
|
209
209
|
def _apply_annotation_settings(self) -> None:
|
|
210
|
-
for widget in
|
|
210
|
+
for widget in self.annotation_widget_list[:]:
|
|
211
211
|
try:
|
|
212
212
|
widget.set_tool(self.annotate_tool_combobox.currentData())
|
|
213
213
|
widget.set_pen(self.annotate_color_combobox.currentData(),
|
|
@@ -244,7 +244,7 @@ class PresentationSettingUI(QWidget):
|
|
|
244
244
|
language_wrapper.language_word_dict.get("cursor_effect_start", "Turn cursor effects on"))
|
|
245
245
|
|
|
246
246
|
def _apply_cursor_settings(self) -> None:
|
|
247
|
-
for widget in
|
|
247
|
+
for widget in self.cursor_widget_list[:]:
|
|
248
248
|
try:
|
|
249
249
|
widget.set_effects(
|
|
250
250
|
ring=self.cursor_ring_checkbox.isChecked(),
|
|
@@ -279,7 +279,7 @@ class PresentationSettingUI(QWidget):
|
|
|
279
279
|
language_wrapper.language_word_dict.get("keystroke_start", "Show keystrokes"))
|
|
280
280
|
|
|
281
281
|
def _on_key_pressed(self, keys) -> None:
|
|
282
|
-
for widget in
|
|
282
|
+
for widget in self.keystroke_widget_list[:]:
|
|
283
283
|
try:
|
|
284
284
|
widget.push_keys(keys)
|
|
285
285
|
except RuntimeError:
|
|
@@ -288,7 +288,7 @@ class PresentationSettingUI(QWidget):
|
|
|
288
288
|
def _on_mouse_clicked(self, x: int, y: int) -> None:
|
|
289
289
|
from PySide6.QtCore import QPoint
|
|
290
290
|
|
|
291
|
-
for widget in
|
|
291
|
+
for widget in self.cursor_widget_list[:]:
|
|
292
292
|
try:
|
|
293
293
|
widget.add_ripple(QPoint(int(x) - widget.x(), int(y) - widget.y()))
|
|
294
294
|
except RuntimeError:
|
|
@@ -324,7 +324,7 @@ class PresentationSettingUI(QWidget):
|
|
|
324
324
|
language_wrapper.language_word_dict.get("magnifier_start", "Turn magnifier on"))
|
|
325
325
|
|
|
326
326
|
def _apply_magnifier_settings(self) -> None:
|
|
327
|
-
for widget in
|
|
327
|
+
for widget in self.magnifier_widget_list[:]:
|
|
328
328
|
try:
|
|
329
329
|
widget.set_zoom(float(self.magnifier_zoom_combobox.currentText()))
|
|
330
330
|
except RuntimeError:
|