From 0c162bb0c871a7543c4d3dffac3de6ac7503c4a7 Mon Sep 17 00:00:00 2001 From: scheianu Date: Mon, 25 Aug 2025 16:37:54 +0300 Subject: [PATCH] UI/UX: Improved mouse hiding logic, overlay controls, and robust player integration --- .../__pycache__/player.cpython-311.pyc | Bin 18892 -> 22503 bytes signage_player/appsettings.py | 90 ++++++++++++++++++ signage_player/main_data/app_config.txt | 5 +- signage_player/main_data/log.txt | 40 ++++++++ signage_player/player.py | 28 +++--- 5 files changed, 148 insertions(+), 15 deletions(-) create mode 100644 signage_player/appsettings.py diff --git a/signage_player/__pycache__/player.cpython-311.pyc b/signage_player/__pycache__/player.cpython-311.pyc index bdecfb226160c82d6b40bf19245c5133b0f2cf41..f6f277ffaa0c73943adf4d02b43e0d9d48b2374d 100644 GIT binary patch delta 7721 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 VV7#r5|Kr}-wO01M9SvsG=zl~|&8q+a diff --git a/signage_player/appsettings.py b/signage_player/appsettings.py new file mode 100644 index 0000000..8a23066 --- /dev/null +++ b/signage_player/appsettings.py @@ -0,0 +1,90 @@ +import tkinter as tk +from tkinter import ttk, messagebox +import json +import os + +CONFIG_PATH = os.path.join(os.path.dirname(__file__), 'main_data', 'app_config.txt') + +class AppSettingsWindow(tk.Tk): + def __init__(self): + super().__init__() + self.title('App Settings') + self.geometry('440x600') # Increased height for better button visibility + self.resizable(False, False) + self.config(bg='#23272e') + self.fields = {} + self.load_config() + self.style = ttk.Style(self) + self.set_styles() + self.create_widgets() + + def set_styles(self): + self.style.theme_use('clam') + self.style.configure('TLabel', background='#23272e', foreground='#e0e0e0', font=('Segoe UI', 13, 'bold')) + self.style.configure('TEntry', fieldbackground='#2c313c', foreground='#e0e0e0', borderwidth=1, relief='flat', font=('Segoe UI', 12)) + self.style.map('TEntry', fieldbackground=[('active', '#23272e')]) + self.style.configure('TButton', background='#3b82f6', foreground='white', font=('Segoe UI', 13, 'bold'), borderwidth=0, focusthickness=3, focuscolor='#60a5fa', padding=8) + self.style.map('TButton', background=[('active', '#2563eb')]) + + def load_config(self): + try: + with open(CONFIG_PATH, 'r') as f: + self.config_data = json.load(f) + except Exception as e: + self.config_data = {} + messagebox.showerror('Error', f'Failed to load config: {e}') + + def save_config(self): + try: + for key, entry in self.fields.items(): + if hasattr(entry, 'get'): + self.config_data[key] = entry.get() + with open(CONFIG_PATH, 'w') as f: + json.dump(self.config_data, f, indent=4) + self.show_custom_popup('Success', 'Settings saved!') + except Exception as e: + messagebox.showerror('Error', f'Failed to save config: {e}') + + def show_custom_popup(self, title, message): + popup = tk.Toplevel(self) + popup.title(title) + popup.geometry('320x120') + popup.configure(bg='#23272e') + popup.resizable(False, False) + popup.attributes('-topmost', True) + ttk.Label(popup, text=title, style='TLabel').pack(pady=(18, 0)) + ttk.Label(popup, text=message, style='TLabel').pack(pady=(8, 0)) + close_btn = ttk.Button(popup, text='OK', style='TButton', command=popup.destroy) + close_btn.pack(pady=18) + popup.grab_set() + popup.after(5000, popup.destroy) + + def create_widgets(self): + title = ttk.Label(self, text='Application Settings', style='TLabel') + title.grid(row=0, column=0, columnspan=2, pady=(18, 6)) + warning = tk.Label(self, text='⚠️ Modify values only if necessary or instructed!', fg='#ffb300', bg='#23272e', font=('Segoe UI', 11, 'bold')) + warning.grid(row=1, column=0, columnspan=2, pady=(0, 18)) + row = 2 + for key, value in self.config_data.items(): + label = ttk.Label(self, text=key+':', style='TLabel') + label.grid(row=row, column=0, sticky='e', padx=18, pady=10) + if key == 'touch_screen': + var = tk.StringVar() + combo = ttk.Combobox(self, textvariable=var, values=['On', 'Off'], state='readonly', width=26) + combo.set(str(value)) + combo.grid(row=row, column=1, padx=10, pady=10) + self.fields[key] = combo + else: + entry = ttk.Entry(self, style='TEntry', width=28) + entry.insert(0, str(value)) + entry.grid(row=row, column=1, padx=10, pady=10) + self.fields[key] = entry + row += 1 + save_btn = ttk.Button(self, text='Save Settings', style='TButton', command=self.save_config) + save_btn.grid(row=row, column=0, pady=30, sticky='e', padx=(0,10)) + close_btn = ttk.Button(self, text='Close', style='TButton', command=self.destroy) + close_btn.grid(row=row, column=1, pady=30, sticky='w', padx=(10,0)) + +if __name__ == '__main__': + app = AppSettingsWindow() + app.mainloop() diff --git a/signage_player/main_data/app_config.txt b/signage_player/main_data/app_config.txt index a27e789..9eb348d 100644 --- a/signage_player/main_data/app_config.txt +++ b/signage_player/main_data/app_config.txt @@ -6,5 +6,6 @@ "port": "80", "screen_w": "1920", "screen_h": "1080", - "refresh_time": "5" -} + "refresh_time": "5", + "touch_screen": "On" +} \ No newline at end of file diff --git a/signage_player/main_data/log.txt b/signage_player/main_data/log.txt index 6eda3ad..b738990 100644 --- a/signage_player/main_data/log.txt +++ b/signage_player/main_data/log.txt @@ -193,3 +193,43 @@ [INFO] [SignageApp] File call-of-duty-black-3840x2160-23674.jpg already exists. Skipping download. [INFO] [SignageApp] Preparing to download demo2.jpeg from http://192.168.1.22/media/demo2.jpeg... [INFO] [SignageApp] File demo2.jpeg already exists. Skipping download. +[INFO] [SignageApp] Fetching playlist from URL: http://192.168.1.22:80/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'} +[INFO] [SignageApp] Server response: {'hashed_quickconnect': '$2b$12$4dxmxuyiezoojRSThjmzQeVsaBscU5vP.9GcTPJhXymmL9JsNklea', 'playlist': [{'duration': 30, 'file_name': 'big-buck-bunny-1080p-60fps-30sec.mp4', 'url': 'http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4'}, {'duration': 10, 'file_name': 'call-of-duty-black-3840x2160-23674.jpg', 'url': 'http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg'}, {'duration': 10, 'file_name': 'demo2.jpeg', 'url': 'http://192.168.1.22/media/demo2.jpeg'}], 'playlist_version': 4} +[INFO] [SignageApp] Fetched updated playlist from server. +[INFO] [SignageApp] Local playlist version: 0, Server playlist version: 4 +[INFO] [SignageApp] Preparing to download big-buck-bunny-1080p-60fps-30sec.mp4 from http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4... +[INFO] [SignageApp] File big-buck-bunny-1080p-60fps-30sec.mp4 already exists. Skipping download. +[INFO] [SignageApp] Preparing to download call-of-duty-black-3840x2160-23674.jpg from http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg... +[INFO] [SignageApp] File call-of-duty-black-3840x2160-23674.jpg already exists. Skipping download. +[INFO] [SignageApp] Preparing to download demo2.jpeg from http://192.168.1.22/media/demo2.jpeg... +[INFO] [SignageApp] File demo2.jpeg already exists. Skipping download. +[INFO] [SignageApp] Fetching playlist from URL: http://192.168.1.22:80/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'} +[INFO] [SignageApp] Server response: {'hashed_quickconnect': '$2b$12$4dxmxuyiezoojRSThjmzQeVsaBscU5vP.9GcTPJhXymmL9JsNklea', 'playlist': [{'duration': 30, 'file_name': 'big-buck-bunny-1080p-60fps-30sec.mp4', 'url': 'http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4'}, {'duration': 10, 'file_name': 'call-of-duty-black-3840x2160-23674.jpg', 'url': 'http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg'}, {'duration': 10, 'file_name': 'demo2.jpeg', 'url': 'http://192.168.1.22/media/demo2.jpeg'}], 'playlist_version': 4} +[INFO] [SignageApp] Fetched updated playlist from server. +[INFO] [SignageApp] Local playlist version: 0, Server playlist version: 4 +[INFO] [SignageApp] Preparing to download big-buck-bunny-1080p-60fps-30sec.mp4 from http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4... +[INFO] [SignageApp] File big-buck-bunny-1080p-60fps-30sec.mp4 already exists. Skipping download. +[INFO] [SignageApp] Preparing to download call-of-duty-black-3840x2160-23674.jpg from http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg... +[INFO] [SignageApp] File call-of-duty-black-3840x2160-23674.jpg already exists. Skipping download. +[INFO] [SignageApp] Preparing to download demo2.jpeg from http://192.168.1.22/media/demo2.jpeg... +[INFO] [SignageApp] File demo2.jpeg already exists. Skipping download. +[INFO] [SignageApp] Fetching playlist from URL: http://192.168.1.22:80/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'} +[INFO] [SignageApp] Server response: {'hashed_quickconnect': '$2b$12$4dxmxuyiezoojRSThjmzQeVsaBscU5vP.9GcTPJhXymmL9JsNklea', 'playlist': [{'duration': 30, 'file_name': 'big-buck-bunny-1080p-60fps-30sec.mp4', 'url': 'http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4'}, {'duration': 10, 'file_name': 'call-of-duty-black-3840x2160-23674.jpg', 'url': 'http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg'}, {'duration': 10, 'file_name': 'demo2.jpeg', 'url': 'http://192.168.1.22/media/demo2.jpeg'}], 'playlist_version': 4} +[INFO] [SignageApp] Fetched updated playlist from server. +[INFO] [SignageApp] Local playlist version: 0, Server playlist version: 4 +[INFO] [SignageApp] Preparing to download big-buck-bunny-1080p-60fps-30sec.mp4 from http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4... +[INFO] [SignageApp] File big-buck-bunny-1080p-60fps-30sec.mp4 already exists. Skipping download. +[INFO] [SignageApp] Preparing to download call-of-duty-black-3840x2160-23674.jpg from http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg... +[INFO] [SignageApp] File call-of-duty-black-3840x2160-23674.jpg already exists. Skipping download. +[INFO] [SignageApp] Preparing to download demo2.jpeg from http://192.168.1.22/media/demo2.jpeg... +[INFO] [SignageApp] File demo2.jpeg already exists. Skipping download. +[INFO] [SignageApp] Fetching playlist from URL: http://192.168.1.22:80/api/playlists with params: {'hostname': 'tv-terasa', 'quickconnect_code': '8887779'} +[INFO] [SignageApp] Server response: {'hashed_quickconnect': '$2b$12$4dxmxuyiezoojRSThjmzQeVsaBscU5vP.9GcTPJhXymmL9JsNklea', 'playlist': [{'duration': 30, 'file_name': 'big-buck-bunny-1080p-60fps-30sec.mp4', 'url': 'http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4'}, {'duration': 10, 'file_name': 'call-of-duty-black-3840x2160-23674.jpg', 'url': 'http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg'}, {'duration': 10, 'file_name': 'demo2.jpeg', 'url': 'http://192.168.1.22/media/demo2.jpeg'}], 'playlist_version': 4} +[INFO] [SignageApp] Fetched updated playlist from server. +[INFO] [SignageApp] Local playlist version: 0, Server playlist version: 4 +[INFO] [SignageApp] Preparing to download big-buck-bunny-1080p-60fps-30sec.mp4 from http://192.168.1.22/media/big-buck-bunny-1080p-60fps-30sec.mp4... +[INFO] [SignageApp] File big-buck-bunny-1080p-60fps-30sec.mp4 already exists. Skipping download. +[INFO] [SignageApp] Preparing to download call-of-duty-black-3840x2160-23674.jpg from http://192.168.1.22/media/call-of-duty-black-3840x2160-23674.jpg... +[INFO] [SignageApp] File call-of-duty-black-3840x2160-23674.jpg already exists. Skipping download. +[INFO] [SignageApp] Preparing to download demo2.jpeg from http://192.168.1.22/media/demo2.jpeg... +[INFO] [SignageApp] File demo2.jpeg already exists. Skipping download. diff --git a/signage_player/player.py b/signage_player/player.py index ee838b2..d6f966a 100644 --- a/signage_player/player.py +++ b/signage_player/player.py @@ -79,9 +79,13 @@ class SimpleTkPlayer: def hide_mouse(self): self.root.config(cursor='none') + if hasattr(self, 'controls_win'): + self.controls_win.config(cursor='none') def show_mouse(self): self.root.config(cursor='arrow') + if hasattr(self, 'controls_win'): + self.controls_win.config(cursor='arrow') def move_mouse_to_corner(self): try: @@ -232,20 +236,18 @@ class SimpleTkPlayer: if self.paused is not True: self.paused = True self.pause_btn.config(text='▶ Resume') - settings_win = tk.Toplevel(self.root) - settings_win.title('Settings') - settings_win.geometry('400x300+100+100') - settings_win.transient(self.root) - settings_win.grab_set() - tk.Label(settings_win, text='Settings', font=('Arial', 18)).pack(pady=10) - # Example setting: close button - tk.Button(settings_win, text='Close', command=settings_win.destroy).pack(pady=20) - def on_close(): - settings_win.grab_release() - settings_win.destroy() + import subprocess, sys + settings_path = os.path.join(os.path.dirname(__file__), 'appsettings.py') + # Open settings in a new process so it doesn't block the main player + proc = subprocess.Popen([sys.executable, settings_path]) + # Wait for the settings window to close, then resume + self.root.after(1000, lambda: self.check_settings_closed(proc)) + + def check_settings_closed(self, proc): + if proc.poll() is not None: self.resume_play() - settings_win.protocol('WM_DELETE_WINDOW', on_close) - settings_win.bind('', lambda e: self.resume_play() if not settings_win.winfo_exists() else None) + else: + self.root.after(1000, lambda: self.check_settings_closed(proc)) def main_start(self): self.play_intro_video()