class ActionsComponent(Component): u""" Simple component that provides undo/redo, record quantization toggle and clip quantization handling. """ undo_button = ButtonControl(**ACTION_BUTTON_COLORS) redo_button = ButtonControl(color=u'Misc.Shift', pressed_color=u'Misc.ShiftOn', disabled_color=u'DefaultButton.Disabled') quantization_on_button = ToggleButtonControl(untoggled_color=u'Misc.Shift', toggled_color=u'Misc.ShiftOn') def __init__(self, *a, **k): self.suppressing_control_notifications = BooleanContext() super(ActionsComponent, self).__init__(*a, **k) self._record_quantization = RecordingQuantization.rec_q_sixtenth self._on_record_quantization_changed_in_live.subject = self.song self._on_record_quantization_changed_in_live() self._metronome_toggle = ToggleComponent(u'metronome', self.song) def control_notifications_enabled(self): return self.is_enabled() and not self.suppressing_control_notifications def quantize_clip(self, clip): raise isinstance(clip, Live.Clip.Clip) or AssertionError clip.quantize(self._record_quantization, 1.0) @undo_button.pressed def undo_button(self, button): if self.song.can_undo: self.song.undo() @redo_button.pressed def redo_button(self, button): if self.song.can_redo: self.song.redo() @quantization_on_button.toggled def quantization_on_button(self, is_toggled, button): self._record_quantization_on = is_toggled self.song.midi_recording_quantization = self._record_quantization if self._record_quantization_on else RecordingQuantization.rec_q_no_q @listens(u'midi_recording_quantization') def _on_record_quantization_changed_in_live(self): quant_value = self.song.midi_recording_quantization quant_on = quant_value != RecordingQuantization.rec_q_no_q if quant_on: self._record_quantization = quant_value self._record_quantization_on = quant_on with self.suppressing_control_notifications(): self.quantization_on_button.is_toggled = quant_on def set_metronome_button(self, button): self._metronome_toggle.set_toggle_button(button) def update(self): super(ActionsComponent, self).update() self._metronome_toggle.update()
class TransportComponent(TransportComponentBase): play_button = ButtonControl(color=u'Transport.PlayOff') jump_encoder = EncoderControl() loop_start_encoder = EncoderControl() def __init__(self, *a, **k): super(TransportComponent, self).__init__(*a, **k) self.__on_signature_numerator_changed.subject = self.song self.__on_signature_denominator_changed.subject = self.song self._session_record_toggle = ToggleComponent(u'session_record', self.song, parent=self) self._calculate_distance_to_move() def set_play_button(self, button): self.play_button.set_control_element(button) def set_session_record_button(self, button): self._session_record_toggle.set_toggle_button(button) @play_button.pressed def play_button(self, _): self.song.start_playing() @jump_encoder.value def jump_encoder(self, value, _): self.song.jump_by(value * self._distance_to_move) @loop_start_encoder.value def loop_start_encoder(self, value, _): self.song.loop_start = max( 0.0, self.song.loop_start + value * self._distance_to_move) @listens(u'signature_numerator') def __on_signature_numerator_changed(self): self._calculate_distance_to_move() @listens(u'signature_denominator') def __on_signature_denominator_changed(self): self._calculate_distance_to_move() def _calculate_distance_to_move(self): self._distance_to_move = old_div(4.0, self.song.signature_denominator ) * self.song.signature_numerator * 64 def _update_button_states(self): super(TransportComponent, self)._update_button_states() self.play_button.color = u'Transport.PlayOn' if self.song.is_playing else u'Transport.PlayOff' def _update_stop_button_color(self): self.stop_button.color = u'Transport.PlayOff' if self.song.is_playing else u'Transport.PlayOn'