import asyncio import tkinter as tk from tkinter import ttk, messagebox # Import messagebox for confirmations import json from async_tkinter_loop import async_handler, async_mainloop from networking import WebSocketClient import color_utils import time from midi import MidiHandler # Import MidiHandler # Dark theme colors (unchanged) bg_color = "#2e2e2e" fg_color = "white" trough_color_red = "#4a0000" trough_color_green = "#004a00" trough_color_blue = "#00004a" trough_color_brightness = "#4a4a4a" trough_color_delay = "#4a4a4a" active_bg_color = "#4a4a4a" highlight_pattern_color = "#6a5acd" # New color for active color in palette active_palette_color_border = "#FFD700" # Gold color class App: def __init__(self) -> None: self.root = tk.Tk() # self.root.attributes("-fullscreen", True) self.root.configure(bg=bg_color) # --- WebSocketClient --- self.websocket_client = WebSocketClient("ws://192.168.4.1:80/ws") self.root.after(100, async_handler(self.websocket_client.connect)) # --- MIDI Handler --- MIDI_PORT_INDEX = 1 # Adjust as needed WEBSOCKET_SERVER_URI = "ws://192.168.4.1:80/ws" self.midi_handler = MidiHandler(MIDI_PORT_INDEX, WEBSOCKET_SERVER_URI) self.midi_task: asyncio.Task | None = None # Start MIDI in background self.root.after(0, async_handler(self.start_midi)) # Configure ttk style (unchanged) style = ttk.Style() style.theme_use("alt") style.configure(".", background=bg_color, foreground=fg_color, font=("Arial", 14)) style.configure("TNotebook", background=bg_color, borderwidth=0) style.configure( "TNotebook.Tab", background=bg_color, foreground=fg_color, font=("Arial", 30), padding=[10, 5] ) # --- Status Frame --- status_frame = ttk.Frame(self.root) status_frame.pack(padx=16, pady=16, fill="x") self.lbl_delay = ttk.Label(status_frame, text="Delay: -") self.lbl_brightness = ttk.Label(status_frame, text="Brightness: -") self.lbl_r = ttk.Label(status_frame, text="R: -") self.lbl_g = ttk.Label(status_frame, text="G: -") self.lbl_b = ttk.Label(status_frame, text="B: -") self.lbl_pattern = ttk.Label(status_frame, text="Pattern: -") self.lbl_n1 = ttk.Label(status_frame, text="n1: -") self.lbl_n2 = ttk.Label(status_frame, text="n2: -") self.lbl_bpm = ttk.Label(status_frame, text="BPM: -") for w in (self.lbl_delay, self.lbl_brightness, self.lbl_r, self.lbl_g, self.lbl_b, self.lbl_pattern, self.lbl_n1, self.lbl_n2, self.lbl_bpm): w.pack(anchor="w") # schedule periodic UI updates self.root.after(200, self.update_status_labels) self.root.protocol("WM_DELETE_WINDOW", self.on_closing) async_mainloop(self.root) @async_handler async def start_midi(self): # Launch MidiHandler.run() as a background task if self.midi_task is None or self.midi_task.done(): self.midi_task = asyncio.create_task(self.midi_handler.run()) def on_closing(self): print("Closing application...") if self.midi_task and not self.midi_task.done(): self.midi_task.cancel() asyncio.create_task(self.websocket_client.close()) self.root.destroy() # --- Asynchronous Update Functions --- @async_handler async def update_rgb(self, tab): pass def update_status_labels(self): # Pull values from midi_handler delay = self.midi_handler.delay brightness = self.midi_handler.brightness r = getattr(self.midi_handler, 'color_r', 0) g = getattr(self.midi_handler, 'color_g', 0) b = getattr(self.midi_handler, 'color_b', 0) pattern = getattr(self.midi_handler, 'current_pattern', '') or '-' n1 = getattr(self.midi_handler, 'n1', '-') n2 = getattr(self.midi_handler, 'n2', '-') bpm = getattr(self.midi_handler, 'current_bpm', None) bpm_text = f"{bpm:.2f}" if isinstance(bpm, (float, int)) else "-" self.lbl_delay.config(text=f"Delay: {delay}") self.lbl_brightness.config(text=f"Brightness: {brightness}") self.lbl_r.config(text=f"R: {r}") self.lbl_g.config(text=f"G: {g}") self.lbl_b.config(text=f"B: {b}") self.lbl_pattern.config(text=f"Pattern: {pattern}") self.lbl_n1.config(text=f"n1: {n1}") self.lbl_n2.config(text=f"n2: {n2}") self.lbl_bpm.config(text=f"BPM: {bpm_text}") # reschedule self.root.after(200, self.update_status_labels) if __name__ == "__main__": app = App()