@ -1125,6 +1125,39 @@ class ArpeggiatorControls(QWidget):
def update_gui_from_engine ( self ) :
""" Update all GUI controls to match engine settings """
try :
# Update root note and octave buttons
if hasattr ( self , ' root_note_buttons ' ) and hasattr ( self . arpeggiator , ' root_note ' ) :
# Extract root note and octave from MIDI note
midi_note = self . arpeggiator . root_note
octave = midi_note / / 12
note_index = midi_note % 12
# Update root note buttons
if self . current_root_note in self . root_note_buttons :
self . apply_button_style ( self . root_note_buttons [ self . current_root_note ] , 12 , " normal " )
self . current_root_note = note_index
if note_index in self . root_note_buttons :
self . apply_button_style ( self . root_note_buttons [ note_index ] , 12 , " active " )
# Update octave buttons
if hasattr ( self , ' octave_buttons ' ) and self . current_octave in self . octave_buttons :
self . apply_button_style ( self . octave_buttons [ self . current_octave ] , 12 , " normal " )
self . current_octave = octave
if octave in self . octave_buttons :
self . apply_button_style ( self . octave_buttons [ octave ] , 12 , " active " )
# Update scale notes display when root note/octave changes
self . update_scale_notes_display ( )
# Update distribution buttons
if hasattr ( self , ' distribution_buttons ' ) and hasattr ( self . arpeggiator , ' channel_distribution ' ) :
# Clear current distribution styling
if self . current_distribution in self . distribution_buttons :
self . apply_button_style ( self . distribution_buttons [ self . current_distribution ] , 12 , " normal " )
# Set new active distribution
self . current_distribution = self . arpeggiator . channel_distribution
if self . current_distribution in self . distribution_buttons :
self . apply_button_style ( self . distribution_buttons [ self . current_distribution ] , 12 , " active " )
# Update scale buttons
if hasattr ( self , ' scale_buttons ' ) :
# Clear current scale styling
@ -1188,12 +1221,72 @@ class ArpeggiatorControls(QWidget):
self . apply_button_style ( self . note_limit_buttons [ self . current_note_limit ] , 12 , " blue " )
# Update delay controls
if hasattr ( self , ' delay_enabled_checkbox ' ) :
self . delay_enabled_checkbox . setChecked ( self . arpeggiator . delay_enabled )
if hasattr ( self , ' delay_toggle ' ) :
self . delay_enabled = self . arpeggiator . delay_enabled
self . delay_toggle . setChecked ( self . delay_enabled )
if self . delay_enabled :
self . delay_toggle . setText ( " ON " )
self . delay_toggle . setStyleSheet ( " background: #2d5a2d; color: white; font-size: 10px; font-weight: bold; " )
# Enable all delay controls
if hasattr ( self , ' delay_length_spin ' ) :
self . delay_length_spin . setEnabled ( True )
if hasattr ( self , ' delay_timing_label ' ) :
self . delay_timing_label . setEnabled ( True )
if hasattr ( self , ' delay_timing_widget ' ) :
self . delay_timing_widget . setEnabled ( True )
if hasattr ( self , ' delay_fade_label ' ) :
self . delay_fade_label . setEnabled ( True )
if hasattr ( self , ' delay_fade_slider ' ) :
self . delay_fade_slider . setEnabled ( True )
if hasattr ( self , ' delay_fade_value ' ) :
self . delay_fade_value . setEnabled ( True )
else :
self . delay_toggle . setText ( " OFF " )
self . delay_toggle . setStyleSheet ( " background: #5a2d2d; color: white; font-size: 10px; font-weight: bold; " )
# Disable all delay controls
if hasattr ( self , ' delay_length_spin ' ) :
self . delay_length_spin . setEnabled ( False )
if hasattr ( self , ' delay_timing_label ' ) :
self . delay_timing_label . setEnabled ( False )
if hasattr ( self , ' delay_timing_widget ' ) :
self . delay_timing_widget . setEnabled ( False )
if hasattr ( self , ' delay_fade_label ' ) :
self . delay_fade_label . setEnabled ( False )
if hasattr ( self , ' delay_fade_slider ' ) :
self . delay_fade_slider . setEnabled ( False )
if hasattr ( self , ' delay_fade_value ' ) :
self . delay_fade_value . setEnabled ( False )
# Update delay timing buttons
if hasattr ( self , ' delay_timing_buttons ' ) and hasattr ( self . arpeggiator , ' delay_timing ' ) :
# Clear current delay timing styling
if hasattr ( self , ' current_delay_timing ' ) and self . current_delay_timing in self . delay_timing_buttons :
self . apply_button_style ( self . delay_timing_buttons [ self . current_delay_timing ] , 10 , " disabled " )
# Set new active delay timing
self . current_delay_timing = self . arpeggiator . delay_timing
if self . current_delay_timing in self . delay_timing_buttons :
if self . delay_enabled :
self . apply_button_style ( self . delay_timing_buttons [ self . current_delay_timing ] , 10 , " purple " )
# Enable and style all timing buttons
for btn in self . delay_timing_buttons . values ( ) :
btn . setEnabled ( True )
if not btn . isChecked ( ) :
self . apply_button_style ( btn , 10 , " normal " )
else :
self . apply_button_style ( self . delay_timing_buttons [ self . current_delay_timing ] , 10 , " disabled " )
# Disable all timing buttons
for btn in self . delay_timing_buttons . values ( ) :
btn . setEnabled ( False )
self . apply_button_style ( btn , 10 , " disabled " )
# Update delay length and fade
if hasattr ( self , ' delay_length_spin ' ) :
self . delay_length_spin . setValue ( self . arpeggiator . delay_length )
if hasattr ( self , ' delay_fade_slider ' ) :
self . delay_fade_slider . setValue ( int ( self . arpeggiator . delay_fade * 100 ) )
if hasattr ( self , ' delay_fade_value ' ) :
self . delay_fade_value . setText ( f " {int(self.arpeggiator.delay_fade * 100)} % " )
# Update sliders and spinboxes
if hasattr ( self , ' gate_slider ' ) :