@ -22,6 +22,7 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					        self . root_note_buttons  =  { }  
			
		
	
		
			
				
					        self . octave_buttons  =  { }  
			
		
	
		
			
				
					        self . scale_buttons  =  { }  
			
		
	
		
			
				
					        self . scale_notes_buttons  =  { }  
			
		
	
		
			
				
					        self . pattern_buttons  =  { }  
			
		
	
		
			
				
					        self . distribution_buttons  =  { }  
			
		
	
		
			
				
					        self . speed_buttons  =  { }  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -40,6 +41,7 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					        self . armed_root_note_button  =  None  
			
		
	
		
			
				
					        self . armed_octave_button  =  None  
			
		
	
		
			
				
					        self . armed_scale_button  =  None  
			
		
	
		
			
				
					        self . armed_scale_note_button  =  None  
			
		
	
		
			
				
					        self . armed_pattern_button  =  None  
			
		
	
		
			
				
					        self . armed_distribution_button  =  None  
			
		
	
		
			
				
					        # Speed changes apply immediately - no armed state needed  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -148,10 +150,22 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        layout . addWidget ( scales_widget )  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Scale notes selection  
			
		
	
		
			
				
					        layout . addWidget ( QLabel ( " Scale Notes: " ) )  
			
		
	
		
			
				
					        scale_notes_widget  =  QWidget ( )  
			
		
	
		
			
				
					        self . scale_notes_layout  =  QGridLayout ( scale_notes_widget )  
			
		
	
		
			
				
					        self . scale_notes_layout . setSpacing ( 2 )  
			
		
	
		
			
				
					        self . scale_notes_buttons  =  { }  
			
		
	
		
			
				
					        self . current_scale_note_index  =  0   # Start from root by default  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Initially populate with major scale notes  
			
		
	
		
			
				
					        self . update_scale_notes_display ( )  
			
		
	
		
			
				
					        layout . addWidget ( scale_notes_widget )  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Octave range dropdown  
			
		
	
		
			
				
					        layout . addWidget ( QLabel ( " Octave Range: " ) )  
			
		
	
		
			
				
					        self . octave_range_combo  =  QComboBox ( )  
			
		
	
		
			
				
					        self . octave_range_combo . setFixedHeight ( 20 )  
			
		
	
		
			
				
					        self . octave_range_combo . setFixedHeight ( 3 0)  
			
		
	
		
			
				
					        for  i  in  range ( 1 ,  5 ) :  
			
		
	
		
			
				
					            self . octave_range_combo . addItem ( f " {i} octave{ ' s '  if i > 1 else  ' ' } " )  
			
		
	
		
			
				
					        layout . addWidget ( self . octave_range_combo )  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -292,7 +306,7 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					        self . tempo_spin . setRange ( 40 ,  200 )  
			
		
	
		
			
				
					        self . tempo_spin . setValue ( 120 )  
			
		
	
		
			
				
					        self . tempo_spin . setSuffix ( "  BPM " )  
			
		
	
		
			
				
					        self . tempo_spin . setFixedHeight ( 2 0)  
			
		
	
		
			
				
					        self . tempo_spin . setFixedHeight ( 3 0)  
			
		
	
		
			
				
					        tempo_layout . addWidget ( self . tempo_spin )  
			
		
	
		
			
				
					        layout . addLayout ( tempo_layout )  
			
		
	
		
			
				
					         
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -327,7 +341,7 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					        self . gate_slider  =  QSlider ( Qt . Horizontal )  
			
		
	
		
			
				
					        self . gate_slider . setRange ( 10 ,  200 )  
			
		
	
		
			
				
					        self . gate_slider . setValue ( 100 )  
			
		
	
		
			
				
					        self . gate_slider . setFixedHeight ( 20  )  
			
		
	
		
			
				
					        self . gate_slider . setFixedHeight ( 25  )  
			
		
	
		
			
				
					        gate_layout . addWidget ( self . gate_slider )  
			
		
	
		
			
				
					        self . gate_label  =  QLabel ( " 100 % " )  
			
		
	
		
			
				
					        self . gate_label . setFixedWidth ( 40 )  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -340,7 +354,7 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					        self . swing_slider  =  QSlider ( Qt . Horizontal )  
			
		
	
		
			
				
					        self . swing_slider . setRange ( - 100 ,  100 )  
			
		
	
		
			
				
					        self . swing_slider . setValue ( 0 )  
			
		
	
		
			
				
					        self . swing_slider . setFixedHeight ( 20  )  
			
		
	
		
			
				
					        self . swing_slider . setFixedHeight ( 25  )  
			
		
	
		
			
				
					        swing_layout . addWidget ( self . swing_slider )  
			
		
	
		
			
				
					        self . swing_label  =  QLabel ( " 0 % " )  
			
		
	
		
			
				
					        self . swing_label . setFixedWidth ( 40 )  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -353,7 +367,7 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					        self . velocity_slider  =  QSlider ( Qt . Horizontal )  
			
		
	
		
			
				
					        self . velocity_slider . setRange ( 1 ,  127 )  
			
		
	
		
			
				
					        self . velocity_slider . setValue ( 80 )  
			
		
	
		
			
				
					        self . velocity_slider . setFixedHeight ( 20  )  
			
		
	
		
			
				
					        self . velocity_slider . setFixedHeight ( 25  )  
			
		
	
		
			
				
					        velocity_layout . addWidget ( self . velocity_slider )  
			
		
	
		
			
				
					        self . velocity_label  =  QLabel ( " 80 " )  
			
		
	
		
			
				
					        self . velocity_label . setFixedWidth ( 40 )  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -383,7 +397,7 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					        self . delay_length_spin . setRange ( 0 ,  8 )  
			
		
	
		
			
				
					        self . delay_length_spin . setValue ( 3 )  
			
		
	
		
			
				
					        self . delay_length_spin . setSuffix ( "  repeats " )  
			
		
	
		
			
				
					        self . delay_length_spin . setFixedHeight ( 2 0)  
			
		
	
		
			
				
					        self . delay_length_spin . setFixedHeight ( 3 0)  
			
		
	
		
			
				
					        self . delay_length_spin . setEnabled ( False )  
			
		
	
		
			
				
					        delay_length_layout . addWidget ( self . delay_length_spin )  
			
		
	
		
			
				
					        delay_layout . addLayout ( delay_length_layout )  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -432,7 +446,7 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					        self . delay_fade_slider  =  QSlider ( Qt . Horizontal )  
			
		
	
		
			
				
					        self . delay_fade_slider . setRange ( 10 ,  90 )  
			
		
	
		
			
				
					        self . delay_fade_slider . setValue ( 30 )   # 30% fade per repeat  
			
		
	
		
			
				
					        self . delay_fade_slider . setFixedHeight ( 20  )  
			
		
	
		
			
				
					        self . delay_fade_slider . setFixedHeight ( 25  )  
			
		
	
		
			
				
					        self . delay_fade_slider . setEnabled ( False )  
			
		
	
		
			
				
					        delay_fade_layout . addWidget ( self . delay_fade_slider )  
			
		
	
		
			
				
					         
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -472,6 +486,7 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        if  hasattr ( self . arpeggiator ,  ' armed_state_changed ' ) :  
			
		
	
		
			
				
					            self . arpeggiator . armed_state_changed . connect ( self . update_armed_states )  
			
		
	
		
			
				
					            self . arpeggiator . settings_changed . connect ( self . update_gui_from_engine )  
			
		
	
		
			
				
					     
			
		
	
		
			
				
					    # Event handlers  
			
		
	
		
			
				
					    def  on_root_note_clicked ( self ,  note_index ) :  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -495,8 +510,14 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					            self . current_root_note  =  note_index  
			
		
	
		
			
				
					            self . root_note_buttons [ note_index ] . setStyleSheet ( " background: #4CAF50; color: white; font-size: 12px; font-weight: bold; padding: 0px; " )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update scale notes display when root note changes  
			
		
	
		
			
				
					            self . update_scale_notes_display ( )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            if  hasattr ( self . arpeggiator ,  ' set_root_note ' ) :  
			
		
	
		
			
				
					                self . arpeggiator . set_root_note ( midi_note )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update starting scale note position  
			
		
	
		
			
				
					            self . update_arpeggiator_scale_note ( )  
			
		
	
		
			
				
					     
			
		
	
		
			
				
					    def  on_octave_clicked ( self ,  octave ) :  
			
		
	
		
			
				
					        midi_note  =  octave  *  12  +  self . current_root_note  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -519,8 +540,14 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					            self . current_octave  =  octave  
			
		
	
		
			
				
					            self . octave_buttons [ octave ] . setStyleSheet ( " background: #4CAF50; color: white; font-size: 12px; font-weight: bold; padding: 0px; " )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update scale notes display when octave changes  
			
		
	
		
			
				
					            self . update_scale_notes_display ( )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            if  hasattr ( self . arpeggiator ,  ' set_root_note ' ) :  
			
		
	
		
			
				
					                self . arpeggiator . set_root_note ( midi_note )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update starting scale note position  
			
		
	
		
			
				
					            self . update_arpeggiator_scale_note ( )  
			
		
	
		
			
				
					     
			
		
	
		
			
				
					    def  on_scale_clicked ( self ,  scale ) :  
			
		
	
		
			
				
					        if  hasattr ( self . arpeggiator ,  ' is_playing ' )  and  self . arpeggiator . is_playing :  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -541,8 +568,15 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					            self . current_scale  =  scale  
			
		
	
		
			
				
					            self . scale_buttons [ scale ] . setStyleSheet ( " background: #4CAF50; color: white; font-size: 12px; font-weight: bold; padding: 0px; " )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update scale notes display when scale changes  
			
		
	
		
			
				
					            self . current_scale_note_index  =  0   # Reset to root when scale changes  
			
		
	
		
			
				
					            self . update_scale_notes_display ( )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            if  hasattr ( self . arpeggiator ,  ' set_scale ' ) :  
			
		
	
		
			
				
					                self . arpeggiator . set_scale ( scale )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update starting scale note position  
			
		
	
		
			
				
					            self . update_arpeggiator_scale_note ( )  
			
		
	
		
			
				
					     
			
		
	
		
			
				
					    def  on_pattern_clicked ( self ,  pattern ) :  
			
		
	
		
			
				
					        if  hasattr ( self . arpeggiator ,  ' is_playing ' )  and  self . arpeggiator . is_playing :  
			
		
	
	
		
			
				
					
						
							
								 
						
						
							
								 
						
						
					 
				
				@ -740,6 +774,9 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					                    self . current_root_note  =  note_index  
			
		
	
		
			
				
					                    btn . setStyleSheet ( " background: #4CAF50; color: white; font-size: 12px; font-weight: bold; padding: 0px; " )  
			
		
	
		
			
				
					                    self . armed_root_note_button  =  None  
			
		
	
		
			
				
					                    # Update scale notes display when root note changes  
			
		
	
		
			
				
					                    self . update_scale_notes_display ( )  
			
		
	
		
			
				
					                    self . update_arpeggiator_scale_note ( )   # Sync with engine  
			
		
	
		
			
				
					                    break  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Octave armed -> active  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -751,6 +788,9 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					                    self . current_octave  =  octave  
			
		
	
		
			
				
					                    btn . setStyleSheet ( " background: #4CAF50; color: white; font-size: 12px; font-weight: bold; padding: 0px; " )  
			
		
	
		
			
				
					                    self . armed_octave_button  =  None  
			
		
	
		
			
				
					                    # Update scale notes display when octave changes  
			
		
	
		
			
				
					                    self . update_scale_notes_display ( )  
			
		
	
		
			
				
					                    self . update_arpeggiator_scale_note ( )   # Sync with engine  
			
		
	
		
			
				
					                    break  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Scale armed -> active  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -762,6 +802,10 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					                    self . current_scale  =  scale  
			
		
	
		
			
				
					                    btn . setStyleSheet ( " background: #4CAF50; color: white; font-size: 12px; font-weight: bold; padding: 0px; " )  
			
		
	
		
			
				
					                    self . armed_scale_button  =  None  
			
		
	
		
			
				
					                    # Update scale notes display when scale changes  
			
		
	
		
			
				
					                    self . current_scale_note_index  =  0   # Reset to root when scale changes  
			
		
	
		
			
				
					                    self . update_scale_notes_display ( )  
			
		
	
		
			
				
					                    self . update_arpeggiator_scale_note ( )   # Sync with engine  
			
		
	
		
			
				
					                    break  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Pattern armed -> active  
			
		
	
	
		
			
				
					
						
						
						
							
								 
						
					 
				
				@ -786,4 +830,181 @@ class ArpeggiatorControls(QWidget): 
			
		
	
		
			
				
					                    self . armed_distribution_button  =  None  
			
		
	
		
			
				
					                    break  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Speed changes apply immediately - no armed state needed  
			
		
	
		
			
				
					        # Scale note armed -> active  
			
		
	
		
			
				
					        if  self . armed_scale_note_button  and  hasattr ( self . arpeggiator ,  ' armed_scale_note_start ' )  and  self . arpeggiator . armed_scale_note_start  is  None :  
			
		
	
		
			
				
					            for  scale_note_index ,  btn  in  self . scale_notes_buttons . items ( ) :  
			
		
	
		
			
				
					                if  btn  ==  self . armed_scale_note_button :  
			
		
	
		
			
				
					                    # Clear old active scale note  
			
		
	
		
			
				
					                    if  self . current_scale_note_index  in  self . scale_notes_buttons :  
			
		
	
		
			
				
					                        self . scale_notes_buttons [ self . current_scale_note_index ] . setStyleSheet ( " background: #3a3a3a; color: #ffffff; font-size: 11px; font-weight: bold; padding: 0px; border: 1px solid #555555; " )  
			
		
	
		
			
				
					                    # Set new active scale note (orange -> blue)  
			
		
	
		
			
				
					                    self . current_scale_note_index  =  scale_note_index  
			
		
	
		
			
				
					                    btn . setStyleSheet ( " background: #0099ff; color: white; font-size: 11px; font-weight: bold; padding: 0px; border: 1px solid #00bbff; " )  
			
		
	
		
			
				
					                    self . armed_scale_note_button  =  None  
			
		
	
		
			
				
					                    break  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Speed changes apply immediately - no armed state needed  
			
		
	
		
			
				
					     
			
		
	
		
			
				
					    def  update_gui_from_engine ( self ) :  
			
		
	
		
			
				
					        """ Update all GUI controls to match engine settings """  
			
		
	
		
			
				
					        try :  
			
		
	
		
			
				
					            # Update scale buttons  
			
		
	
		
			
				
					            if  hasattr ( self ,  ' scale_buttons ' ) :  
			
		
	
		
			
				
					                # Clear current scale styling  
			
		
	
		
			
				
					                if  hasattr ( self ,  ' current_scale ' )  and  self . current_scale  in  self . scale_buttons :  
			
		
	
		
			
				
					                    self . scale_buttons [ self . current_scale ] . setStyleSheet ( " font-size: 12px; font-weight: bold; padding: 0px; " )  
			
		
	
		
			
				
					                # Set new active scale  
			
		
	
		
			
				
					                self . current_scale  =  self . arpeggiator . scale  
			
		
	
		
			
				
					                if  self . current_scale  in  self . scale_buttons :  
			
		
	
		
			
				
					                    self . scale_buttons [ self . current_scale ] . setStyleSheet ( " background: #4CAF50; color: white; font-size: 12px; font-weight: bold; padding: 0px; " )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update pattern buttons  
			
		
	
		
			
				
					            if  hasattr ( self ,  ' pattern_buttons ' ) :  
			
		
	
		
			
				
					                # Clear current pattern styling  
			
		
	
		
			
				
					                if  hasattr ( self ,  ' current_pattern ' )  and  self . current_pattern  in  self . pattern_buttons :  
			
		
	
		
			
				
					                    self . pattern_buttons [ self . current_pattern ] . setStyleSheet ( " font-size: 12px; font-weight: bold; padding: 0px; " )  
			
		
	
		
			
				
					                # Set new active pattern  
			
		
	
		
			
				
					                self . current_pattern  =  self . arpeggiator . pattern_type  
			
		
	
		
			
				
					                if  self . current_pattern  in  self . pattern_buttons :  
			
		
	
		
			
				
					                    self . pattern_buttons [ self . current_pattern ] . setStyleSheet ( " background: #4CAF50; color: white; font-size: 12px; font-weight: bold; padding: 0px; " )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update scale note buttons  
			
		
	
		
			
				
					            if  hasattr ( self ,  ' scale_notes_buttons ' ) :  
			
		
	
		
			
				
					                # Clear current scale note styling  
			
		
	
		
			
				
					                if  hasattr ( self ,  ' current_scale_note_index ' )  and  self . current_scale_note_index  in  self . scale_notes_buttons :  
			
		
	
		
			
				
					                    self . scale_notes_buttons [ self . current_scale_note_index ] . setStyleSheet ( " background: #3a3a3a; color: #ffffff; font-size: 11px; font-weight: bold; padding: 0px; border: 1px solid #555555; " )  
			
		
	
		
			
				
					                # Set new active scale note  
			
		
	
		
			
				
					                self . current_scale_note_index  =  getattr ( self . arpeggiator ,  ' scale_note_start ' ,  0 )  
			
		
	
		
			
				
					                if  self . current_scale_note_index  in  self . scale_notes_buttons :  
			
		
	
		
			
				
					                    self . scale_notes_buttons [ self . current_scale_note_index ] . setStyleSheet ( " background: #0099ff; color: white; font-size: 11px; font-weight: bold; padding: 0px; border: 1px solid #00bbff; " )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update note speed buttons  
			
		
	
		
			
				
					            if  hasattr ( self ,  ' speed_buttons ' ) :  
			
		
	
		
			
				
					                # Clear current speed styling  
			
		
	
		
			
				
					                if  hasattr ( self ,  ' current_speed ' )  and  self . current_speed  in  self . speed_buttons :  
			
		
	
		
			
				
					                    self . speed_buttons [ self . current_speed ] . setStyleSheet ( " background: #3a3a3a; color: #ffffff; font-size: 12px; font-weight: bold; padding: 0px; border: 1px solid #555555; " )  
			
		
	
		
			
				
					                # Set new active speed  
			
		
	
		
			
				
					                self . current_speed  =  self . arpeggiator . note_speed  
			
		
	
		
			
				
					                if  self . current_speed  in  self . speed_buttons :  
			
		
	
		
			
				
					                    self . speed_buttons [ self . current_speed ] . setStyleSheet ( " background: #9933cc; color: white; font-size: 12px; font-weight: bold; padding: 0px; border: 1px solid #bb55ee; " )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update pattern length buttons  
			
		
	
		
			
				
					            if  hasattr ( self ,  ' pattern_length_buttons ' ) :  
			
		
	
		
			
				
					                # Clear current pattern length styling  
			
		
	
		
			
				
					                if  hasattr ( self ,  ' current_pattern_length ' )  and  self . current_pattern_length  in  self . pattern_length_buttons :  
			
		
	
		
			
				
					                    self . pattern_length_buttons [ self . current_pattern_length ] . setStyleSheet ( " background: #3a3a3a; color: #ffffff; font-size: 12px; font-weight: bold; padding: 0px; border: 1px solid #555555; " )  
			
		
	
		
			
				
					                # Set new active pattern length  
			
		
	
		
			
				
					                if  hasattr ( self . arpeggiator ,  ' user_pattern_length ' ) :  
			
		
	
		
			
				
					                    self . current_pattern_length  =  self . arpeggiator . user_pattern_length  
			
		
	
		
			
				
					                    if  self . current_pattern_length  in  self . pattern_length_buttons :  
			
		
	
		
			
				
					                        self . pattern_length_buttons [ self . current_pattern_length ] . setStyleSheet ( " background: #cc6600; color: white; font-size: 12px; font-weight: bold; padding: 0px; border: 1px solid #ee8800; " )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update delay controls  
			
		
	
		
			
				
					            if  hasattr ( self ,  ' delay_enabled_checkbox ' ) :  
			
		
	
		
			
				
					                self . delay_enabled_checkbox . setChecked ( self . arpeggiator . delay_enabled )  
			
		
	
		
			
				
					            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 ) )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update sliders and spinboxes  
			
		
	
		
			
				
					            if  hasattr ( self ,  ' gate_slider ' ) :  
			
		
	
		
			
				
					                self . gate_slider . setValue ( int ( self . arpeggiator . gate  *  100 ) )  
			
		
	
		
			
				
					            if  hasattr ( self ,  ' swing_slider ' ) :  
			
		
	
		
			
				
					                self . swing_slider . setValue ( int ( self . arpeggiator . swing  *  100 ) )  
			
		
	
		
			
				
					            if  hasattr ( self ,  ' velocity_slider ' ) :  
			
		
	
		
			
				
					                self . velocity_slider . setValue ( self . arpeggiator . velocity )  
			
		
	
		
			
				
					            if  hasattr ( self ,  ' octave_range_combo ' ) :  
			
		
	
		
			
				
					                self . octave_range_combo . setCurrentIndex ( self . arpeggiator . octave_range  -  1 )  
			
		
	
		
			
				
					            if  hasattr ( self ,  ' tempo_spin ' ) :  
			
		
	
		
			
				
					                self . tempo_spin . setValue ( int ( self . arpeggiator . tempo ) )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					        except  Exception  as  e :  
			
		
	
		
			
				
					            print ( f " Error updating GUI from engine: {e} " )  
			
		
	
		
			
				
					     
			
		
	
		
			
				
					    def  update_scale_notes_display ( self ) :  
			
		
	
		
			
				
					        """ Update the scale notes buttons based on current root note and scale """  
			
		
	
		
			
				
					        # Clear existing buttons  
			
		
	
		
			
				
					        for  button  in  self . scale_notes_buttons . values ( ) :  
			
		
	
		
			
				
					            button . deleteLater ( )  
			
		
	
		
			
				
					        self . scale_notes_buttons . clear ( )  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Get the scale definition  
			
		
	
		
			
				
					        scale_intervals  =  self . arpeggiator . SCALES . get ( self . current_scale ,  [ 0 ,  2 ,  4 ,  5 ,  7 ,  9 ,  11 ] )  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Note names for display  
			
		
	
		
			
				
					        note_names  =  [ " C " ,  " C# " ,  " D " ,  " D# " ,  " E " ,  " F " ,  " F# " ,  " G " ,  " G# " ,  " A " ,  " A# " ,  " B " ]  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Calculate the actual MIDI notes for this scale  
			
		
	
		
			
				
					        root_midi  =  self . current_octave  *  12  +  self . current_root_note  
			
		
	
		
			
				
					        scale_notes  =  [ ]  
			
		
	
		
			
				
					        for  interval  in  scale_intervals :  
			
		
	
		
			
				
					            scale_notes . append ( root_midi  +  interval )  
			
		
	
		
			
				
					         
			
		
	
		
			
				
					        # Create buttons for each scale note  
			
		
	
		
			
				
					        for  i ,  midi_note  in  enumerate ( scale_notes ) :  
			
		
	
		
			
				
					            note_name  =  note_names [ midi_note  %  12 ]  
			
		
	
		
			
				
					            octave  =  midi_note  / /  12  
			
		
	
		
			
				
					            display_text  =  f " {note_name}{octave} "  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            btn  =  QPushButton ( display_text )  
			
		
	
		
			
				
					            btn . setFixedSize ( 50 ,  25 )  
			
		
	
		
			
				
					            btn . setCheckable ( True )  
			
		
	
		
			
				
					            btn . setStyleSheet ( " background: #3a3a3a; color: #ffffff; font-size: 11px; font-weight: bold; padding: 0px; border: 1px solid #555555; " )  
			
		
	
		
			
				
					            btn . clicked . connect ( lambda  checked ,  idx = i :  self . on_scale_note_clicked ( idx ) )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Set first note (root) as selected by default  
			
		
	
		
			
				
					            if  i  ==  self . current_scale_note_index :  
			
		
	
		
			
				
					                btn . setChecked ( True )  
			
		
	
		
			
				
					                btn . setStyleSheet ( " background: #0099ff; color: white; font-size: 11px; font-weight: bold; padding: 0px; border: 1px solid #00bbff; " )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            self . scale_notes_buttons [ i ]  =  btn  
			
		
	
		
			
				
					            self . scale_notes_layout . addWidget ( btn ,  0 ,  i )  
			
		
	
		
			
				
					     
			
		
	
		
			
				
					    def  on_scale_note_clicked ( self ,  scale_note_index ) :  
			
		
	
		
			
				
					        """ Handle scale note selection with armed state support """  
			
		
	
		
			
				
					        if  hasattr ( self . arpeggiator ,  ' is_playing ' )  and  self . arpeggiator . is_playing :  
			
		
	
		
			
				
					            # ARMED STATE - button turns orange, waits for pattern end  
			
		
	
		
			
				
					            if  self . armed_scale_note_button :  
			
		
	
		
			
				
					                # Reset previous armed button  
			
		
	
		
			
				
					                old_armed_index  =  None  
			
		
	
		
			
				
					                for  idx ,  btn  in  self . scale_notes_buttons . items ( ) :  
			
		
	
		
			
				
					                    if  btn  ==  self . armed_scale_note_button :  
			
		
	
		
			
				
					                        old_armed_index  =  idx  
			
		
	
		
			
				
					                        break  
			
		
	
		
			
				
					                if  old_armed_index  is  not  None :  
			
		
	
		
			
				
					                    if  old_armed_index  ==  self . current_scale_note_index :  
			
		
	
		
			
				
					                        # It was the current active note, make it blue again  
			
		
	
		
			
				
					                        self . armed_scale_note_button . setStyleSheet ( " background: #0099ff; color: white; font-size: 11px; font-weight: bold; padding: 0px; border: 1px solid #00bbff; " )  
			
		
	
		
			
				
					                    else :  
			
		
	
		
			
				
					                        # It was just armed, make it gray again  
			
		
	
		
			
				
					                        self . armed_scale_note_button . setStyleSheet ( " background: #3a3a3a; color: #ffffff; font-size: 11px; font-weight: bold; padding: 0px; border: 1px solid #555555; " )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Set new armed button to orange  
			
		
	
		
			
				
					            self . armed_scale_note_button  =  self . scale_notes_buttons [ scale_note_index ]  
			
		
	
		
			
				
					            self . scale_notes_buttons [ scale_note_index ] . setStyleSheet ( " background: #ff8800; color: white; font-size: 11px; font-weight: bold; padding: 0px; border: 1px solid #ffaa00; " )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Arm the scale note change in the engine  
			
		
	
		
			
				
					            if  hasattr ( self . arpeggiator ,  ' arm_scale_note_start ' ) :  
			
		
	
		
			
				
					                self . arpeggiator . arm_scale_note_start ( scale_note_index )  
			
		
	
		
			
				
					        else :  
			
		
	
		
			
				
					            # IMMEDIATE CHANGE - apply right away  
			
		
	
		
			
				
					            old_index  =  self . current_scale_note_index  
			
		
	
		
			
				
					            self . current_scale_note_index  =  scale_note_index  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update button styling  
			
		
	
		
			
				
					            if  old_index  in  self . scale_notes_buttons :  
			
		
	
		
			
				
					                self . scale_notes_buttons [ old_index ] . setChecked ( False )  
			
		
	
		
			
				
					                self . scale_notes_buttons [ old_index ] . setStyleSheet ( " background: #3a3a3a; color: #ffffff; font-size: 11px; font-weight: bold; padding: 0px; border: 1px solid #555555; " )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            if  scale_note_index  in  self . scale_notes_buttons :  
			
		
	
		
			
				
					                self . scale_notes_buttons [ scale_note_index ] . setChecked ( True )  
			
		
	
		
			
				
					                self . scale_notes_buttons [ scale_note_index ] . setStyleSheet ( " background: #0099ff; color: white; font-size: 11px; font-weight: bold; padding: 0px; border: 1px solid #00bbff; " )  
			
		
	
		
			
				
					             
			
		
	
		
			
				
					            # Update arpeggiator engine with new starting scale note  
			
		
	
		
			
				
					            self . update_arpeggiator_scale_note ( )  
			
		
	
		
			
				
					     
			
		
	
		
			
				
					    def  update_arpeggiator_scale_note ( self ) :  
			
		
	
		
			
				
					        """ Update the arpeggiator engine with the selected scale note starting position """  
			
		
	
		
			
				
					        if  hasattr ( self . arpeggiator ,  ' set_scale_note_start ' ) :  
			
		
	
		
			
				
					            self . arpeggiator . set_scale_note_start ( self . current_scale_note_index )