Add MIDI device persistence functionality
- Add configuration file system to remember MIDI device selection - Load saved MIDI device preference on application startup - Automatically save MIDI device selection when changed - Handle device disconnection gracefully with fallback - Smart initialization with validation and error handling - Create config.json for storing device preferences - Improve user experience by eliminating need to re-select device
This commit is contained in:
43
src/main.py
43
src/main.py
@@ -2,6 +2,7 @@ import asyncio
|
||||
import tkinter as tk
|
||||
from tkinter import ttk, messagebox # Import messagebox for confirmations
|
||||
import json
|
||||
import os
|
||||
from async_tkinter_loop import async_handler, async_mainloop
|
||||
from networking import WebSocketClient
|
||||
import color_utils
|
||||
@@ -10,6 +11,9 @@ import mido # Import mido for MIDI port detection
|
||||
import time
|
||||
from midi import MidiHandler # Import MidiHandler
|
||||
|
||||
# Configuration file path
|
||||
CONFIG_FILE = "config.json"
|
||||
|
||||
# Dark theme colors (unchanged)
|
||||
bg_color = "#2e2e2e"
|
||||
fg_color = "white"
|
||||
@@ -36,11 +40,11 @@ class App:
|
||||
|
||||
# --- MIDI Configuration ---
|
||||
self.available_midi_ports = self.get_midi_ports()
|
||||
self.current_midi_port_index = 0 # Default to first port
|
||||
self.current_midi_port_index = self.load_midi_device_preference() # Load saved preference
|
||||
self.midi_handler: MidiHandler | None = None
|
||||
self.midi_task: asyncio.Task | None = None
|
||||
|
||||
# Initialize MIDI handler with first available port (will be done after GUI is created)
|
||||
# Initialize MIDI handler with saved port (will be done after GUI is created)
|
||||
self.pending_midi_init = True if self.available_midi_ports else False
|
||||
|
||||
# Configure ttk style (unchanged)
|
||||
@@ -61,7 +65,12 @@ class App:
|
||||
# MIDI port dropdown
|
||||
self.midi_port_var = tk.StringVar()
|
||||
if self.available_midi_ports:
|
||||
self.midi_port_var.set(self.available_midi_ports[0])
|
||||
# Set to saved preference if available, otherwise first port
|
||||
if 0 <= self.current_midi_port_index < len(self.available_midi_ports):
|
||||
self.midi_port_var.set(self.available_midi_ports[self.current_midi_port_index])
|
||||
else:
|
||||
self.midi_port_var.set(self.available_midi_ports[0])
|
||||
self.current_midi_port_index = 0
|
||||
|
||||
midi_dropdown = ttk.Combobox(
|
||||
midi_frame,
|
||||
@@ -230,6 +239,32 @@ class App:
|
||||
|
||||
async_mainloop(self.root)
|
||||
|
||||
def load_midi_device_preference(self):
|
||||
"""Load saved MIDI device preference from config file"""
|
||||
try:
|
||||
if os.path.exists(CONFIG_FILE):
|
||||
with open(CONFIG_FILE, 'r') as f:
|
||||
config = json.load(f)
|
||||
saved_index = config.get('midi_device_index', 0)
|
||||
print(f"Loaded MIDI device preference: index {saved_index}")
|
||||
return saved_index
|
||||
except Exception as e:
|
||||
print(f"Error loading MIDI device preference: {e}")
|
||||
return 0 # Default to first port
|
||||
|
||||
def save_midi_device_preference(self):
|
||||
"""Save current MIDI device preference to config file"""
|
||||
try:
|
||||
config = {
|
||||
'midi_device_index': self.current_midi_port_index,
|
||||
'midi_device_name': self.available_midi_ports[self.current_midi_port_index] if self.available_midi_ports else None
|
||||
}
|
||||
with open(CONFIG_FILE, 'w') as f:
|
||||
json.dump(config, f, indent=2)
|
||||
print(f"Saved MIDI device preference: {config['midi_device_name']} (index {config['midi_device_index']})")
|
||||
except Exception as e:
|
||||
print(f"Error saving MIDI device preference: {e}")
|
||||
|
||||
def get_midi_ports(self):
|
||||
"""Get list of available MIDI input ports"""
|
||||
try:
|
||||
@@ -286,6 +321,7 @@ class App:
|
||||
# Current selection is no longer available, select first available
|
||||
self.midi_port_var.set(self.available_midi_ports[0])
|
||||
self.current_midi_port_index = 0
|
||||
self.save_midi_device_preference() # Save the new preference
|
||||
self.restart_midi_handler()
|
||||
elif not self.available_midi_ports:
|
||||
# No ports available
|
||||
@@ -305,6 +341,7 @@ class App:
|
||||
if selected_port in self.available_midi_ports:
|
||||
self.current_midi_port_index = self.available_midi_ports.index(selected_port)
|
||||
print(f"MIDI port changed to: {selected_port} (index: {self.current_midi_port_index})")
|
||||
self.save_midi_device_preference() # Save the new preference
|
||||
self.restart_midi_handler()
|
||||
|
||||
@async_handler
|
||||
|
Reference in New Issue
Block a user