diff --git a/gui/arpeggiator_controls.py b/gui/arpeggiator_controls.py index d7d8769..5bff8b3 100644 --- a/gui/arpeggiator_controls.py +++ b/gui/arpeggiator_controls.py @@ -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'):