def _setup_session(self):
     num_pads = len(PAD_TRANSLATIONS)
     self._track_left_button = ButtonElement(not IS_MOMENTARY, MIDI_CC_TYPE,
                                             0, 36)
     self._track_right_button = ButtonElement(not IS_MOMENTARY,
                                              MIDI_CC_TYPE, 0, 35)
     self._session = SessionComponent(8, 0)
     self._session.name = 'Session_Control'
     self._session.selected_scene().name = 'Selected_Scene'
     self._session.set_mixer(self._mixer)
     self._session.set_page_left_button(self._track_left_button)
     self._session.set_page_right_button(self._track_right_button)
     pads = []
     for index in range(num_pads):
         pads.append(
             ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 0, 60 + index))
         pads[(-1)].name = 'Pad_' + str(index)
         clip_slot = self._session.selected_scene().clip_slot(index)
         clip_slot.set_triggered_to_play_value(GREEN_BLINK)
         clip_slot.set_triggered_to_record_value(RED_BLINK)
         clip_slot.set_stopped_value(AMBER_FULL)
         clip_slot.set_started_value(GREEN_FULL)
         clip_slot.set_recording_value(RED_FULL)
         clip_slot.set_launch_button(pads[(-1)])
         clip_slot.name = str(index) + '_Selected_Clip_Slot'
    def _setup_mixer_control(self):
        is_momentary = True
        mixer = MixerComponent(NUM_TRACKS, 2)
        for track in range(NUM_TRACKS):
            strip = mixer.channel_strip(track)
            strip.set_volume_control(SliderElement(MIDI_CC_TYPE, track, 23))
            strip.set_pan_control(
                EncoderElement(MIDI_CC_TYPE, track, 10,
                               Live.MidiMap.MapMode.absolute))
            strip.set_send_controls(
                (EncoderElement(MIDI_CC_TYPE, track, 19,
                                Live.MidiMap.MapMode.absolute),
                 EncoderElement(MIDI_CC_TYPE, track, 20,
                                Live.MidiMap.MapMode.absolute)))
            strip.set_solo_button(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 64))
            strip.set_mute_button(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 63))
            strip.set_crossfade_toggle(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 65))
            eq = mixer.track_eq(track)
            eq.set_gain_controls(
                tuple([
                    EncoderElement(MIDI_CC_TYPE, track, 18 - index,
                                   Live.MidiMap.MapMode.absolute)
                    for index in range(3)
                ]))
            eq.set_cut_buttons(
                tuple([
                    ButtonElement(is_momentary, MIDI_NOTE_TYPE, track,
                                  62 - index) for index in range(3)
                ]))
            filter = mixer.track_filter(track)
            filter.set_filter_controls(
                EncoderElement(MIDI_CC_TYPE, track, 22,
                               Live.MidiMap.MapMode.absolute),
                EncoderElement(MIDI_CC_TYPE, track, 21,
                               Live.MidiMap.MapMode.absolute))

        for ret_track in range(2):
            strip = mixer.return_strip(ret_track)
            strip.set_volume_control(
                SliderElement(MIDI_CC_TYPE, 12, 22 + ret_track))
            strip.set_pan_control(
                EncoderElement(MIDI_CC_TYPE, 12, 20 + ret_track,
                               Live.MidiMap.MapMode.absolute))
            strip.set_mute_button(
                ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12,
                              78 + ret_track))

        mixer.set_crossfader_control(SliderElement(MIDI_CC_TYPE, 12, 8))
        mixer.set_prehear_volume_control(
            EncoderElement(MIDI_CC_TYPE, 12, 24,
                           Live.MidiMap.MapMode.absolute))
        mixer.master_strip().set_volume_control(
            SliderElement(MIDI_CC_TYPE, 12, 7))
        mixer.master_strip().set_pan_control(
            EncoderElement(MIDI_CC_TYPE, 12, 10,
                           Live.MidiMap.MapMode.absolute))
        return mixer
    def _setup_device(self):
        encoders = []
        for index in range(8):
            encoders.append(
                PeekableEncoderElement(
                    MIDI_CC_TYPE, 1, index,
                    Live.MidiMap.MapMode.relative_binary_offset))
            encoders[(-1)].set_feedback_delay(-1)
            encoders[(-1)].add_value_listener((self._encoder_value),
                                              identify_sender=True)
            encoders[(-1)].name = 'Device_Control_' + str(index)

        self._encoders = tuple(encoders)
        self._prev_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1,
                                               12)
        self._next_bank_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 1,
                                               11)
        self._prev_bank_button.name = 'Device_Bank_Down_Button'
        self._next_bank_button.name = 'Device_Bank_Up_Button'
        device = DeviceComponent(device_selection_follows_track_selection=True)
        device.name = 'Device_Component'
        self.set_device_component(device)
        device.set_parameter_controls(self._encoders)
        device.set_bank_nav_buttons(self._prev_bank_button,
                                    self._next_bank_button)
Example #4
0
 def disconnect(self):
     ButtonElement.disconnect(self)
     self._is_enabled = None
     self._color_source = None
     self._report_input = None
     self._column_index = None
     self._row_index = None
 def __init__(self, c_instance):
     ControlSurface.__init__(self, c_instance)
     with self.component_guard():
         self.set_pad_translations(PAD_TRANSLATIONS)
         self._suggested_input_port = 'DirectLink'
         self._suggested_output_port = 'DirectLink'
         self._waiting_for_first_response = True
         self._has_sliders = True
         self._current_midi_map = None
         self._display_reset_delay = -1
         self._shift_pressed = False
         self._shift_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE, 15,
                                            13)
         self._master_slider = SliderElement(MIDI_CC_TYPE, 15, 41)
         self._next_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE,
                                               15, 111)
         self._prev_nav_button = ButtonElement(IS_MOMENTARY, MIDI_CC_TYPE,
                                               15, 110)
         self._device_bank_buttons = None
         self._device_navigation = None
         self._shift_button.name = 'Shift_Button'
         self._master_slider.name = 'Master_Volume_Control'
         self._next_nav_button.name = 'Next_Track_Button'
         self._prev_nav_button.name = 'Prev_Track_Button'
         self._master_slider.add_value_listener((self._slider_value),
                                                identify_sender=True)
         self._shift_button.add_value_listener(self._shift_value)
         self._setup_mixer()
         self._setup_transport_and_session()
         self._setup_device()
         self._setup_display()
         for component in self.components:
             component.set_enabled(False)
Example #6
0
 def __init__(self, modeselector, editsection, *a, **k):
     super(CompoundComponent, self).__init__(*a, **k)
     self._modesel = modeselector
     self._editsection = editsection
     is_momentary = True
     self._do_push_button.subject = ButtonElement(is_momentary,
                                                  MIDI_CC_TYPE, 0, 82)
     self._do_edit_slider.subject = SliderElement(MIDI_CC_TYPE, 1, 81)
     self._do_channel_slider.subject = SliderElement(MIDI_CC_TYPE, 1, 83)
     self._do_channel_button.subject = ButtonElement(
         is_momentary, MIDI_CC_TYPE, 1, 63)
     self._do_req_quantize.subject = SliderElement(MIDI_CC_TYPE, 1, 100)
     self._do_browse.subject = SliderElement(MIDI_CC_TYPE, 1, 84)
     self._do_tempo.subject = SliderElement(MIDI_CC_TYPE, 1, 101)
     self._do_volume.subject = SliderElement(MIDI_CC_TYPE, 1, 103)
     self._do_dedicated_rec_quantize.subject = SliderElement(
         MIDI_CC_TYPE, 2, 112)
     self._do_dedicated_clip_quantize.subject = SliderElement(
         MIDI_CC_TYPE, 2, 113)
     self.set_up_function_buttons()
     self._wheel_overide = None
     self.scrub_mode = True
     self.select_arm_mode = True
     self._push_down = False
     return
    def receive_value(self, value):
        self._is_notifying = True
        ButtonElement.receive_value(self, value)
        self._is_notifying = False
        for listener in self._pending_listeners:
            self.add_value_listener(listener[0], listener[1])

        self._pending_listeners = []
Example #8
0
 def set_touch_mode(self, touchchannel):
     self.touch_mode = True
     nr_dev_ctrl = len(self._parameter_controls)
     for ctrl in self._parameter_controls:
         touch_button = ButtonElement(False, MIDI_CC_TYPE, touchchannel,
                                      ctrl.message_identifier())
         self.del_touch_buttons.append(touch_button)
         touch_button.add_value_listener(self._clear_param, True)
Example #9
0
	def __init__(self, *a, **k):
		ControlSurface.__init__(self, *a, **k)
		with self.component_guard():
			self._monomod_version = 'b996'
			self._host_name = 'LaunchMod'
			self._color_type = 'Launchpad'
			self._timer = 0
			self._suppress_send_midi = True
			self._suppress_session_highlight = True
			self._suppress_highlight = False
			is_momentary = True
			self._suggested_input_port = 'Launchpad'
			self._suggested_output_port = 'Launchpad'
			self._control_is_with_automap = False
			self._user_byte_write_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 16)
			self._user_byte_write_button.name = 'User_Byte_Button'
			self._user_byte_write_button.send_value(1)
			self._user_byte_write_button.add_value_listener(self._user_byte_value)
			self._wrote_user_byte = False
			self._challenge = Live.Application.get_random_int(0, 400000000) & 2139062143
			matrix = ButtonMatrixElement()
			matrix.name = 'Button_Matrix'
			for row in range(8):
				button_row = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, row * 16 + column, str(column) + '_Clip_' + str(row) + '_Button', self) for column in range(8) ]
				matrix.add_row(tuple(button_row))

			self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0, optimized_send_midi=False)
			self._config_button.add_value_listener(self._config_value)
			top_button_names = ['Bank_Select_Up_Button',
			 'Bank_Select_Down_Button',
			 'Bank_Select_Left_Button',
			 'Bank_Select_Right_Button',
			 'Session_Button',
			 'User1_Button',
			 'User2_Button',
			 'Mixer_Button']
			side_button_names = ['Vol_Button',
			 'Pan_Button',
			 'SndA_Button',
			 'SndB_Button',
			 'Stop_Button',
			 'Trk_On_Button',
			 'Solo_Button',
			 'Arm_Button']
			top_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index, top_button_names[index], self) for index in range(8) ]
			side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index], side_button_names[index], self) for index in range(8) ]
			self._side_buttons = ButtonMatrixElement()
			self._side_buttons.add_row(side_buttons)
			self._setup_monobridge()
			self._setup_mod()
			self._selector = MainSelectorComponent(self, matrix, tuple(top_buttons), tuple(side_buttons), self._config_button)
			self._selector.name = 'Main_Modes'
			for control in self.controls:
				isinstance(control, MonoButtonElement) and control.add_value_listener(self._button_value)
			self.set_highlighting_session_component(self._selector.session_component())
			self._suppress_session_highlight = False
		self.log_message('--------------= ' + str(self._monomod_version) + ' log opened =--------------')	
Example #10
0
	def __init__(self, *a, **k):
		ControlSurface.__init__(self, *a, **k)
		self._skin = Skin(LaunchModColors)
		with self.component_guard():
			self._monomod_version = 'b996'
			self._host_name = 'LaunchMod'
			self._color_type = 'Launchpad'
			self._timer = 0
			self._suppress_send_midi = True
			self._suppress_session_highlight = True
			self._suppress_highlight = False
			is_momentary = True
			self._suggested_input_port = 'Launchpad'
			self._suggested_output_port = 'Launchpad'
			self._control_is_with_automap = False
			self._user_byte_write_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 16)
			self._user_byte_write_button.name = 'User_Byte_Button'
			self._user_byte_write_button.send_value(1)
			self._user_byte_write_button.add_value_listener(self._user_byte_value)
			self._wrote_user_byte = False
			self._challenge = Live.Application.get_random_int(0, 400000000) & 2139062143
			matrix = ButtonMatrixElement(name = 'Button_Matrix')
			for row in range(8):
				button_row = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, row * 16 + column, str(column) + '_Clip_' + str(row) + '_Button', self, skin = self._skin) for column in range(8) ]
				matrix.add_row(tuple(button_row))
			self._matrix = matrix
			self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0, optimized_send_midi=False)
			self._config_button.add_value_listener(self._config_value)
			top_button_names = ['Bank_Select_Up_Button',
			 'Bank_Select_Down_Button',
			 'Bank_Select_Left_Button',
			 'Bank_Select_Right_Button',
			 'Session_Button',
			 'User1_Button',
			 'User2_Button',
			 'Mixer_Button']
			side_button_names = ['Vol_Button',
			 'Pan_Button',
			 'SndA_Button',
			 'SndB_Button',
			 'Stop_Button',
			 'Trk_On_Button',
			 'Solo_Button',
			 'Arm_Button']
			top_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index, top_button_names[index], self, skin = self._skin) for index in range(8) ]
			self._top_buttons = top_buttons
			side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index], side_button_names[index], self, skin = self._skin) for index in range(8) ]
			self._side_buttons = ButtonMatrixElement(name = 'SideButtons', rows = [side_buttons])
			self._setup_monobridge()
			self._setup_mod()
			self._selector = MainSelectorComponent(self, matrix, tuple(top_buttons), tuple(side_buttons), self._config_button)
			self._selector.name = 'Main_Modes'
			for control in self.controls:
				isinstance(control, MonoButtonElement) and control.add_value_listener(self._button_value)
			self.set_highlighting_session_component(self._selector.session_component())
			self._suppress_session_highlight = False
		self.log_message('--------------= ' + str(self._monomod_version) + ' log opened =--------------')	
 def __init__(self, is_momentary, msg_type, channel, identifier, send_channel=None, identifier_send_offset=0, send_msg_type=None):
     ButtonElement.__init__(self, is_momentary, msg_type, channel, identifier)
     self._send_channel = send_channel
     self._send_msg_type = send_msg_type
     self._identifier_send_offset = identifier_send_offset
     self._on_value = AMB_FULL
     self._off_value = LED_OFF
     self._is_enabled = True
     self._is_notifying = False
     self._force_next_value = False
     self._pending_listeners = []
 def _setup_view_control(self):
     is_momentary = True
     view = ViewTogglerComponent(NUM_TRACKS)
     view.set_buttons(
         tuple([
             ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 67)
             for track in range(NUM_TRACKS)
         ]),
         tuple([
             ButtonElement(is_momentary, MIDI_NOTE_TYPE, track, 66)
             for track in range(NUM_TRACKS)
         ]))
Example #13
0
 def __init__(self, is_momentary, midi_type, identifier, channel,
              color_list):
     ButtonElement.__init__(self, is_momentary, midi_type, channel,
                            identifier)
     self._msg_identifier = identifier
     self._color_list = color_list
     self._last_color = None
     self._last_index = 0
     self._midi_type = midi_type
     self._IndexedButton__note_on_code = MIDI_NOTE_ON_STATUS | channel
     self._IndexedButton__grabbed = False
     self._IndexedButton__resource_hander = None
Example #14
0
 def __init__(self, is_momentary, channel, row_index, column_index,
              color_source):
     ButtonElement.__init__(self, is_momentary, MIDI_NOTE_TYPE, channel,
                            MATRIX_NOTE_NR + row_index * 8 + column_index)
     self._is_enabled = True
     self._color_source = color_source
     self._row_index = row_index
     self._column_index = column_index
     self.last_value = None
     self.set_channel(NON_FEEDBACK_CHANNEL)
     self.state = 0
     self._PadColorButton__cc_enabled = True
Example #15
0
 def __init__(self):
     SessionComponent.__init__(self, 4, 4)
     self._mode_button = ButtonElement(False, MIDI_CC_TYPE, 2, 50)
     self._do_matrix_adv_mode.subject = self._mode_button
     self._mode_button.send_value(0, True)
     self._track_banking_increment = 1
     self._c_mode_button = ButtonElement(True, MIDI_CC_TYPE, 2, 90)
     self._change_color_mode.subject = self._c_mode_button
     self._c_mode_button.send_value(0, True)
     self.notify = self.notify_standard
     self.get_color = self.get_color_standard
     self._nav_color_button = self.canonical_parent.create_gated_button(8, 110)
     self._toggle_step_advance.subject = self._nav_color_button
     self._nav_color_button.switch_off()
     self._color_manager = self
Example #16
0
 def install_connections(self, install_translation_callback,
                         install_mapping_callback,
                         install_forwarding_callback):
     if self._is_enabled:
         ButtonElement.install_connections(self,
                                           install_translation_callback,
                                           install_mapping_callback,
                                           install_forwarding_callback)
     else:
         if self._msg_channel != self._original_channel or self._msg_identifier != self._original_identifier:
             install_translation_callback(self._msg_type,
                                          self._original_identifier,
                                          self._original_channel,
                                          self._msg_identifier,
                                          self._msg_channel)
 def __init__(self):
     SessionComponent.__init__(self, 4, 4)
     self._matrix = None
     self._advance = STEP4
     self._mode_button = None
     self._set_mode_button(ButtonElement(False, MIDI_CC_TYPE, 0, 80))
     self.set_track_banking_increment(STEP4)
Example #18
0
    def __init__(self,
                 c_instance,
                 control_factory=LaunchkeyControlFactory(),
                 identity_response=SIZE_RESPONSE):
        ControlSurface.__init__(self, c_instance)
        self._control_factory = control_factory
        self._identity_response = identity_response
        with self.component_guard():
            self.set_pad_translations(PAD_TRANSLATIONS)
            self._suggested_input_port = 'Launchkey InControl'
            self._suggested_output_port = 'Launchkey InControl'
            self._has_sliders = True
            self._current_midi_map = None
            self._master_slider = make_slider(7, 'Master_Volume_Control')
            self._modes_buttons = []
            for index in range(3):
                button = ButtonElement(IS_MOMENTARY, MIDI_NOTE_TYPE, 0,
                                       13 + index)
                self._modes_buttons.append(button)
                self._modes_buttons[(-1)].add_value_listener(
                    self._dummy_listener)

            self._setup_mixer()
            self._setup_session()
            self._setup_transport()
            self._setup_device()
            self._setup_navigation()
            for component in self.components:
                component.set_enabled(False)
 def _setup_session_control(self):
     is_momentary = True
     down_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 89)
     up_button = ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 90)
     session = SessionComponent(NUM_TRACKS, 0)
     session.set_select_buttons(down_button, up_button)
     session.selected_scene().set_launch_button(
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, 12, 87))
     track_stop_buttons = [
         ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 68)
         for index in range(NUM_TRACKS)
     ]
     session.set_stop_track_clip_buttons(tuple(track_stop_buttons))
     for index in range(NUM_TRACKS):
         session.selected_scene().clip_slot(index).set_launch_button(
             ButtonElement(is_momentary, MIDI_NOTE_TYPE, index, 69))
Example #20
0
 def __init__(self, parent):
     SessionComponent.__init__(self, 4, 4)
     self._parent = parent
     self._matrix = None
     self._advance = STEP4
     self._mode_button = None
     self._set_mode_button(ButtonElement(False, MIDI_CC_TYPE, 0, 80))
     self._linkoff = 0
Example #21
0
 def set_up_function_buttons(self):
     is_momentary = True
     self._do_octave_button.subject = StateButton(is_momentary,
                                                  MIDI_CC_TYPE, 1, 70)
     self._do_scale_button.subject = StateButton(is_momentary, MIDI_CC_TYPE,
                                                 1, 71)
     self._do_note_button.subject = StateButton(is_momentary, MIDI_CC_TYPE,
                                                1, 72)
     self._do_loop_mod.subject = StateButton(is_momentary, MIDI_CC_TYPE, 1,
                                             69)
     self._color_edit_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 3,
                                             114)
     self._do_color_button.subject = self._color_edit_button
     self.scrub_mode_button = StateButton(is_momentary, MIDI_CC_TYPE, 2, 53)
     self._action_scrub_mode.subject = self.scrub_mode_button
     self._action_loop_button.subject = StateButton(is_momentary,
                                                    MIDI_CC_TYPE, 2, 54)
     self._action_quant_button.subject = StateButton(
         is_momentary, MIDI_CC_TYPE, 2, 55)
Example #22
0
 def __init__(self, *a, **k):
     (super().__init__)(*a, **k)
     is_momentary = True
     self.split_knob = SliderElement(MIDI_CC_TYPE, 5, 70)
     self.gate_knob = SliderElement(MIDI_CC_TYPE, 5, 71)
     self.bend_knob = SliderElement(MIDI_CC_TYPE, 5, 72)
     self.offset_knob = SliderElement(MIDI_CC_TYPE, 5, 73)
     self.strech_knob = SliderElement(MIDI_CC_TYPE, 5, 74)
     self.fade_knob = SliderElement(MIDI_CC_TYPE, 5, 75)
     self.transpose_knob = SliderElement(MIDI_CC_TYPE, 5, 77)
     self.edit_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 5, 60)
     self.split_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 5, 61)
     self.init_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 5, 62)
     self.delete_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 5, 63)
     self.select_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 5, 64)
     self._do_edit_button.subject = self.edit_button
     self._do_split_button.subject = self.split_button
     self._do_delete.subject = self.delete_button
     self._do_init.subject = self.init_button
     self._do_select.subject = self.select_button
     self._do_split.subject = self.split_knob
     self._do_gate.subject = self.gate_knob
     self._do_bend.subject = self.bend_knob
     self._do_offset.subject = self.offset_knob
     self._do_strech.subject = self.strech_knob
     self._do_fade.subject = self.fade_knob
     self._do_transpose.subject = self.transpose_knob
Example #23
0
 def __init__(self, button_index, monochrome=False, *a, **k):
     (super().__init__)(button_index, *a, **k)
     self._note_display_mode = ND_KEYBOARD1
     self.current_scale_index = 0
     self._scale = None
     self._base_note = 0
     self._octave = 0.55
     self.current_scale_index = 0
     self._in_edit_mode = False
     self._editmode = None
     self._is_monochrome = monochrome
     self._color_edit_assign = monochrome and self.assign_edit_mono or self.assign_edit_color
     self.assign_transpose(SCALES[self.current_scale_index])
     is_momentary = True
     self.octave_down_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 3,
                                             120)
     self.octave_up_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 3,
                                           121)
     self.base_down_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 3,
                                           124)
     self.base_up_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 3, 125)
     self.scale_down_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 3,
                                            118)
     self.scale_up_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 3,
                                          119)
     self._adjust_scale.subject = SliderElement(MIDI_CC_TYPE, 2, 116)
     self._adjust_octav.subject = SliderElement(MIDI_CC_TYPE, 2, 115)
     self._adjust_basem.subject = SliderElement(MIDI_CC_TYPE, 2, 117)
     self._do_oct_down.subject = self.octave_down_button
     self._do_oct_up.subject = self.octave_up_button
     self._do_base_down.subject = self.base_down_button
     self._do_base_up.subject = self.base_up_button
     self._do_scale_down.subject = self.scale_down_button
     self._do_scale_up.subject = self.scale_up_button
     self._seg_display = None
    def _setup_mixer_control(self):
        is_momentary = True
        num_tracks = 8
        num_returns = 7
        mixer = MixerComponent(num_tracks, num_returns)
        for track in range(num_tracks):
            strip = mixer.channel_strip(track)
            strip.set_volume_control(
                SliderElement(MIDI_CC_TYPE, 15, 54 - track))
            strip.set_pan_control(SliderElement(MIDI_CC_TYPE, 15, 80 - track))
            strip.set_mute_button(
                ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 117 - track))
            strip.set_invert_mute_feedback(True)

        for track in range(num_returns):
            strip = mixer.return_strip(track)
            strip.set_volume_control(
                SliderElement(MIDI_CC_TYPE, 15, 10 + track))

        mixer.set_bank_buttons(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 108),
            ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 109))
        mixer.set_crossfader_control(SliderElement(MIDI_CC_TYPE, 15, 9))
        mixer.master_strip().set_volume_control(
            SliderElement(MIDI_CC_TYPE, 15, 46))
        session = SessionComponent(0, 0)
        session.set_select_buttons(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 95),
            ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 92))
        session.selected_scene().set_launch_button(
            ButtonElement(is_momentary, MIDI_CC_TYPE, 15, 91))
Example #25
0
 def __init__(self, *a, **k):
     (super().__init__)(*a, **k)
     is_momentary = True
     self.mikro_shift_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 2, 80)
     self._do_shift_mikro.subject = self.mikro_shift_button
     self.shift_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 1, 80)
     self._do_shift.subject = self.shift_button
     self.alt_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 1, 82)
     self._do_alt.subject = self.alt_button
     self.mikro_shift = False
     self.shiftdown = False
     self.altdown = False
     self.edit_state = ES_NONE
     self._down_button = None
     self._action_set_quant.subject = SliderElement(MIDI_CC_TYPE, 2, 110)
     self._action_init_loop.subject = SliderElement(MIDI_CC_TYPE, 2, 111)
     self._nav_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 115)
     self._action_navigate.subject = self._nav_button
     self._copy_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 95)
     self._action_duplicate.subject = self._copy_button
     self._quantize_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 97)
     self._action_quantize.subject = self._quantize_button
     self._paste_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 96)
     self._action_new.subject = self._paste_button
     self._note_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 101)
     self._action_note.subject = self._note_button
     self._clear_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 103)
     self._action_clear.subject = self._clear_button
     self._nudge_button = StateButton(is_momentary, MIDI_CC_TYPE, 0, 100)
     self._action_nudge_button.subject = self._nudge_button
     self.action_time = False
     self.pad_action = False
     self.pad_wheel_action = False
     self.quantize = 5
     self.quantize_amount = 1.0
     self.initial_clip_len = 4.0
     self._focused_clip = None
     self._focused_c_index = None
     self._color_edit = False
     self.nav_index = 0
Example #26
0
def make_button(identifier,
                msg_type=MIDI_NOTE_TYPE,
                is_momentary=True,
                skin=None,
                is_modifier=False,
                name=''):
    return ButtonElement(
        is_momentary,
        msg_type,
        STANDARD_CHANNEL,
        identifier,
        skin=skin,
        name=name,
        resource_type=(PrioritizedResource if is_modifier else None))
 def __init__(self, *a, **k):
     super(JogWheelSection, self).__init__(*a, **k)
     self._do_encoder_button.subject = ButtonElement(
         True, MIDI_CC_TYPE, 0, CC_JOGWHEEL_PUSH)
     self._do_encoder_touch.subject = ButtonElement(True, MIDI_CC_TYPE, 0,
                                                    CC_JOGWHEEL_TOUCH)
     self._do_encoder_slider.subject = SliderElement(
         MIDI_CC_TYPE, 0, CC_JOGWHEEL)
     self.__nav_left_button = IndexedButton(True, MIDI_CC_TYPE, CC_NAV_LEFT,
                                            0, (0, 127))
     self.__nav_right_button = IndexedButton(True, MIDI_CC_TYPE,
                                             CC_NAV_RIGHT, 0, (0, 127))
     self.__nav_up_button = IndexedButton(True, MIDI_CC_TYPE, CC_NAV_UP, 0,
                                          (0, 127))
     self.__nav_down_button = IndexedButton(True, MIDI_CC_TYPE, CC_NAV_DOWN,
                                            0, (0, 127))
     self._do_nav_left.subject = self.__nav_left_button
     self._do_nav_right.subject = self.__nav_right_button
     self._do_nav_up.subject = self.__nav_up_button
     self._do_nav_down.subject = self.__nav_down_button
     self._selected_track_change.subject = self.song().view
     self._clip = None
     return
Example #28
0
 def _create_controls(self):
     self._device_controls = ButtonMatrixElement(rows=[[EncoderElement(MIDI_CC_TYPE, (self.encoder_msg_channel), identifier, (Live.MidiMap.MapMode.relative_smooth_two_compliment), name=('Encoder_%d_%d' % (column_index, row_index))) for column_index, identifier in enumerate(row)] for row_index, row in enumerate((
      self.encoder_msg_ids[:4], self.encoder_msg_ids[8:12]))])
     self._horizontal_scroll_encoder = EncoderElement(MIDI_CC_TYPE,
       (self.encoder_msg_channel),
       (self.encoder_msg_ids[7]),
       (Live.MidiMap.MapMode.relative_smooth_two_compliment),
       name='Horizontal_Scroll_Encoder')
     self._vertical_scroll_encoder = EncoderElement(MIDI_CC_TYPE,
       (self.encoder_msg_channel),
       (self.encoder_msg_ids[15]),
       (Live.MidiMap.MapMode.relative_smooth_two_compliment),
       name='Vertical_Scroll_Encoder')
     self._volume_encoder = EncoderElement(MIDI_CC_TYPE,
       (self.encoder_msg_channel),
       (self.encoder_msg_ids[13]),
       (Live.MidiMap.MapMode.relative_smooth_two_compliment),
       name='Volume_Encoder')
     self._pan_encoder = EncoderElement(MIDI_CC_TYPE,
       (self.encoder_msg_channel),
       (self.encoder_msg_ids[12]),
       (Live.MidiMap.MapMode.relative_smooth_two_compliment),
       name='Pan_Encoder')
     self._send_a_encoder = EncoderElement(MIDI_CC_TYPE,
       (self.encoder_msg_channel),
       (self.encoder_msg_ids[4]),
       (Live.MidiMap.MapMode.relative_smooth_two_compliment),
       name='Send_A_Encoder')
     self._send_b_encoder = EncoderElement(MIDI_CC_TYPE,
       (self.encoder_msg_channel),
       (self.encoder_msg_ids[5]),
       (Live.MidiMap.MapMode.relative_smooth_two_compliment),
       name='Send_B_Encoder')
     self._send_encoders = ButtonMatrixElement(rows=[
      [
       self._send_a_encoder, self._send_b_encoder]])
     self._return_a_encoder = EncoderElement(MIDI_CC_TYPE,
       (self.encoder_msg_channel),
       (self.encoder_msg_ids[6]),
       (Live.MidiMap.MapMode.relative_smooth_two_compliment),
       name='Return_A_Encoder')
     self._return_b_encoder = EncoderElement(MIDI_CC_TYPE,
       (self.encoder_msg_channel),
       (self.encoder_msg_ids[14]),
       (Live.MidiMap.MapMode.relative_smooth_two_compliment),
       name='Return_B_Encoder')
     self._return_encoders = ButtonMatrixElement(rows=[
      [
       self._return_a_encoder, self._return_b_encoder]])
     self._pads = ButtonMatrixElement(rows=[[ButtonElement(True, MIDI_NOTE_TYPE, (self.pad_channel), (col + 36 + 8 * row), name=('Pad_%d_%d' % (col, row))) for col in range(8)] for row in range(2)])
def make_button(identifier,
                channel,
                name,
                msg_type=MIDI_NOTE_TYPE,
                skin=None,
                is_modifier=False):
    return ButtonElement(
        True,
        msg_type,
        channel,
        identifier,
        skin=skin,
        name=name,
        resource_type=(PrioritizedResource if is_modifier else None))
def make_ring_encoder(encoder_identifer, button_identifier, name='', *a, **k):
    button_name = '%s_Ring_Mode_Button' % name
    button = ButtonElement(False,
                           MIDI_CC_TYPE,
                           0,
                           button_identifier,
                           name=button_name)
    encoder = RingedEncoderElement(MIDI_CC_TYPE,
                                   0,
                                   encoder_identifer, (MapMode.absolute),
                                   *a,
                                   name=name,
                                   **k)
    encoder.set_ring_mode_button(button)
    return encoder
def make_button(name,
                identifier,
                channel=0,
                msg_type=MIDI_NOTE_TYPE,
                is_momentary=True,
                is_modifier=False,
                skin=None):
    return ButtonElement(
        is_momentary,
        msg_type,
        channel,
        identifier,
        name=name,
        resource_type=(PrioritizedResource if is_modifier else None),
        skin=skin)
Example #32
0
class LaunchMod(Launchpad):


	def __init__(self, *a, **k):
		ControlSurface.__init__(self, *a, **k)
		with self.component_guard():
			self._monomod_version = 'b996'
			self._host_name = 'LaunchMod'
			self._color_type = 'Launchpad'
			self._timer = 0
			self._suppress_send_midi = True
			self._suppress_session_highlight = True
			self._suppress_highlight = False
			is_momentary = True
			self._suggested_input_port = 'Launchpad'
			self._suggested_output_port = 'Launchpad'
			self._control_is_with_automap = False
			self._user_byte_write_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 16)
			self._user_byte_write_button.name = 'User_Byte_Button'
			self._user_byte_write_button.send_value(1)
			self._user_byte_write_button.add_value_listener(self._user_byte_value)
			self._wrote_user_byte = False
			self._challenge = Live.Application.get_random_int(0, 400000000) & 2139062143
			matrix = ButtonMatrixElement()
			matrix.name = 'Button_Matrix'
			for row in range(8):
				button_row = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, row * 16 + column, str(column) + '_Clip_' + str(row) + '_Button', self) for column in range(8) ]
				matrix.add_row(tuple(button_row))

			self._config_button = ButtonElement(is_momentary, MIDI_CC_TYPE, 0, 0, optimized_send_midi=False)
			self._config_button.add_value_listener(self._config_value)
			top_button_names = ['Bank_Select_Up_Button',
			 'Bank_Select_Down_Button',
			 'Bank_Select_Left_Button',
			 'Bank_Select_Right_Button',
			 'Session_Button',
			 'User1_Button',
			 'User2_Button',
			 'Mixer_Button']
			side_button_names = ['Vol_Button',
			 'Pan_Button',
			 'SndA_Button',
			 'SndB_Button',
			 'Stop_Button',
			 'Trk_On_Button',
			 'Solo_Button',
			 'Arm_Button']
			top_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_CC_TYPE, 0, 104 + index, top_button_names[index], self) for index in range(8) ]
			side_buttons = [ ConfigurableButtonElement(is_momentary, MIDI_NOTE_TYPE, 0, SIDE_NOTES[index], side_button_names[index], self) for index in range(8) ]
			self._side_buttons = ButtonMatrixElement()
			self._side_buttons.add_row(side_buttons)
			self._setup_monobridge()
			self._setup_mod()
			self._selector = MainSelectorComponent(self, matrix, tuple(top_buttons), tuple(side_buttons), self._config_button)
			self._selector.name = 'Main_Modes'
			for control in self.controls:
				isinstance(control, MonoButtonElement) and control.add_value_listener(self._button_value)
			self.set_highlighting_session_component(self._selector.session_component())
			self._suppress_session_highlight = False
		self.log_message('--------------= ' + str(self._monomod_version) + ' log opened =--------------')	
	

	"""Mono overrides and additions"""
	def _setup_monobridge(self):
		self._monobridge = MonoBridgeElement(self)
		self._monobridge.name = 'MonoBridge'
	

	def _setup_mod(self):
		self.monomodular = get_monomodular(self)
		self.monomodular.name = 'monomodular_switcher'
		self.modhandler = LaunchModHandler(self)
		self.modhandler.name = 'ModHandler'
		#self.modhandler.layer = Layer( lock_button = self._note_mode_button, push_grid = self._matrix, shift_button = self._shift_button, alt_button = self._select_button, key_buttons = self._track_state_buttons)
		#self.modhandler.layer.priority = 4
		#self.modhandler.nav_buttons_layer = AddLayerMode( self.modhandler, Layer(nav_up_button = self._nav_up_button, nav_down_button = self._nav_down_button, nav_left_button = self._nav_left_button, nav_right_button = self._nav_right_button) )
	

	def update_display(self):
		ControlSurface.update_display(self)
		self._timer = (self._timer + 1) % 256
		self.flash()
	

	def flash(self):
		if self.modhandler.is_enabled():
			for control in self.controls:
				if isinstance(control, MonoButtonElement):
					control.flash(self._timer)
	

	def disconnect(self):
		super(LaunchMod, self).disconnect()
		rebuild_sys()
class MaschineSessionComponent(SessionComponent):
    __module__ = __name__
    __doc__ = 'Session Component for Maschine'
    scene_component_type = ModSceneComponent
    _session_mode = None
    _advance = STEP1
    _matrix = None
    _color_manager = None

    def __init__(self):
        SessionComponent.__init__(self, 4, 4)
        self._mode_button = ButtonElement(False, MIDI_CC_TYPE, 2, 50)
        self._do_matrix_adv_mode.subject = self._mode_button
        self._mode_button.send_value(0, True)
        self._track_banking_increment = 1
        self._c_mode_button = ButtonElement(True, MIDI_CC_TYPE, 2, 90)
        self._change_color_mode.subject = self._c_mode_button
        self._c_mode_button.send_value(0, True)
        self.notify = self.notify_standard
        self.get_color = self.get_color_standard
        self._nav_color_button = self.canonical_parent.create_gated_button(8, 110)
        self._toggle_step_advance.subject = self._nav_color_button
        self._nav_color_button.switch_off()
        self._color_manager = self

    def set_mode(self, mode):
        self._session_mode = mode

    def set_color_manager(self, manager):
        if manager:
            self._color_manager = manager

    @subject_slot('value')
    def _change_color_mode(self, value):
        if value > 0:
            if self.is_color_mode():
                self.set_color_mode(False)
                self._session_mode.refresh()
                self._c_mode_button.send_value(0, True)
            else:
                self.set_color_mode(True)
                self._session_mode.refresh()
                self._c_mode_button.send_value(1, True)

    def set_color_mode(self, colormode):
        if colormode:
            self.notify = self.notify_cmode
            self.get_color = self.get_color_cmode
        else:
            self.notify = self.notify_standard
            self.get_color = self.get_color_standard

    def is_color_mode(self):
        return self.notify == self.notify_cmode

    def start_up(self):
        self.set_enabled(True)

    def update_nav_button(self):
        color = self._advance == STEP4 and COLOR_HUE_NAV4 or COLOR_HUE_NAV
        self._bank_up_button.hue = color
        self._bank_down_button.hue = color
        self._bank_left_button.hue = color
        self._bank_right_button.hue = color
        self._horizontal_banking.update()
        self._vertical_banking.update()

    @subject_slot('value')
    def _toggle_step_advance(self, value):
        if value != 0:
            self.set_step_advance(self._advance == STEP4 and STEP1 or STEP4)

    def switch_step_advance(self):
        self.set_step_advance(self._advance == STEP4 and STEP1 or STEP4)

    def set_step_advance(self, value):
        self._advance = value
        if self._advance == STEP4:
            self._mode_button.send_value(127, True)
            self._nav_color_button.turn_on()
        else:
            self._mode_button.send_value(0, True)
            self._nav_color_button.switch_off()
        self.set_track_banking_increment(self._advance)
        self.update_nav_button()

    def get_step_advance(self):
        return self._advance

    def _link(self):
        pass

    def get_track_offset(self):
        return self._track_offset

    def get_scene_offset(self):
        return self._scene_offset

    def set_matrix(self, matrix):
        self._matrix = matrix

    def set_track_banking_increment(self, increment):
        self._track_banking_increment = increment

    @subject_slot('value')
    def _do_matrix_adv_mode(self, value):
        if not self._mode_button != None:
            raise AssertionError
            if not value in range(128):
                raise AssertionError
                self._advance = value != 0 and self._advance == STEP1 and STEP4
                self._mode_button.send_value(127, True)
                self._nav_color_button.turn_on()
                self.set_track_banking_increment(STEP4)
            else:
                self._advance = STEP1
                self._mode_button.send_value(0, True)
                self._nav_color_button.switch_off()
                self.set_track_banking_increment(STEP1)

    def update(self):
        SessionComponent.update(self)
        try:
            self._advance
        except AttributeError:
            pass
        else:
            if self._advance == STEP4:
                self._mode_button.send_value(127, True)
            else:
                self._mode_button.send_value(0, True)

    def get_controled_clip_slots(self, clip_slot):
        if clip_slot.controls_other_clips:
            track = clip_slot.canonical_parent
            if track.is_foldable:
                song = self.song()
                index = vindex(song.tracks, track)
                if index >= 0:
                    count = index
                    done = False
                    result = []
                    while not done:
                        count += 1
                        if count == len(song.tracks):
                            done = True
                        else:
                            ctrack = song.tracks[count]

    def get_color_cmode(self, clip_slot):
        if clip_slot == None:
            return PColor.OFF
        color = self.get_color_cmode_base(clip_slot)
        oncolor = color[0]
        offcolor = color[1]
        if clip_slot.has_clip:
            if clip_slot.clip.is_recording or clip_slot.clip.will_record_on_start:
                return (oncolor, oncolor)
            elif clip_slot.clip.is_triggered:
                return (oncolor, oncolor)
            elif clip_slot.clip.is_playing:
                return (oncolor, oncolor)
            else:
                return (offcolor, offcolor)
        elif clip_slot.will_record_on_start:
            return CLR_REC
        elif clip_slot.is_playing:
            return PColor.CLIP_GROUP_PLAY
        elif clip_slot.controls_other_clips:
            return PColor.CLIP_GROUP_CONTROL
        elif clip_slot.is_triggered:
            return CLR_TRIGG
        return PColor.OFF

    def get_color_standard(self, clip_slot):
        if not clip_slot:
            return PColor.OFF
        if clip_slot.has_clip:
            if clip_slot.clip.is_recording or clip_slot.clip.will_record_on_start:
                if clip_slot.clip.is_triggered:
                    return PColor.CLIP_RECORD_TRIGGER
                else:
                    return PColor.CLIP_RECORD
            if clip_slot.clip.is_playing:
                return PColor.CLIP_PLAY
            elif clip_slot.clip.is_triggered:
                return PColor.CLIP_PLAY_TRIGGER
            else:
                return PColor.CLIP_STOPPED
        elif clip_slot.will_record_on_start:
            return PColor.CLIP_RECORD_TRIGGER
        elif clip_slot.is_playing:
            return PColor.CLIP_GROUP_PLAY
        elif clip_slot.controls_other_clips:
            return PColor.CLIP_GROUP_CONTROL
        elif clip_slot.is_triggered:
            return PColor.CLIP_GROUP_TRIGGER
        return PColor.OFF

    def get_mono_state(self, clip_slot):
        if not clip_slot:
            return (0, 0)
        if clip_slot.has_clip:
            if clip_slot.clip.is_recording or clip_slot.clip.will_record_on_start:
                if clip_slot.clip.is_triggered:
                    return (1, 2)
                else:
                    return (1, 1)
            if clip_slot.clip.is_playing:
                return (1, 1)
            elif clip_slot.clip.is_triggered:
                return (1, 2)
            else:
                return (1, 0)
        elif clip_slot.will_record_on_start:
            return (1, 2)
        elif clip_slot.is_playing:
            return (1, 1)
        elif clip_slot.controls_other_clips:
            return (1, 0)
        elif clip_slot.is_triggered:
            return (1, 2)
        return (0, 0)

    def notify_standard(self, blink):
        index = blink / 2
        for scene_index in range(4):
            scene = self.scene(scene_index)
            for track_index in range(4):
                clip_slot = scene.clip_slot(track_index)._clip_slot
                if clip_slot:
                    button = self._matrix[scene_index][track_index]
                    color = self.get_color_standard(clip_slot)
                    if button != None and clip_slot.has_clip:
                        if clip_slot.clip.is_triggered:
                            button.send_color_direct(color[index])
                    elif clip_slot.is_triggered:
                        button.send_color_direct(color[index])

    def notify_cmode(self, blink):
        sblink = blink / 2
        fblink = blink % 2
        for scene_index in range(4):
            scene = self.scene(scene_index)
            for track_index in range(4):
                clip_slot = scene.clip_slot(track_index)._clip_slot
                if clip_slot:
                    button = self._matrix[scene_index][track_index]
                    color = self.get_color_cmode_base(clip_slot)
                    if clip_slot.has_clip:
                        if clip_slot.clip.is_recording or clip_slot.clip.will_record_on_start:
                            button.send_color_direct(sblink == 0 and color[0] or REC)
                        elif clip_slot.clip.is_triggered:
                            button.send_color_direct(color[sblink])
                        elif clip_slot.clip.is_playing:
                            button.send_color_direct(color[0])
                        else:
                            button.send_color_direct(color[1])
                    elif clip_slot.will_record_on_start:
                        button.send_color_direct(sblink == 0 and REC or REC_DIM)
                    elif clip_slot.is_playing:
                        button.send_color_direct(PColor.CLIP_GROUP_PLAY[0])
                    elif clip_slot.controls_other_clips:
                        button.send_color_direct(PColor.CLIP_GROUP_CONTROL[0])
                    elif clip_slot.is_triggered:
                        button.send_color_direct(sblink == 0 and TRIGG or TRIGG_DIM)

    def convertToHSB(self, rgb_color):
        return toHSB(rgb_color)

    def get_color_cmode_base(self, clip_slot):
        if clip_slot != None:
            if clip_slot.has_clip:
                rgb = clip_slot.clip.color
                color = self._color_manager.convertToHSB(clip_slot.clip.color)
                return color
            elif clip_slot.controls_other_clips:
                pass
        return PColor.OFF

    def notify_mono(self, blink):
        sblink = blink / 2
        fblink = blink % 2
        for scene_index in range(4):
            scene = self.scene(scene_index)
            for track_index in range(4):
                clip_slot = scene.clip_slot(track_index)._clip_slot
                button = self._matrix[scene_index][track_index]
                if clip_slot != None:
                    state = self.get_mono_state(clip_slot)
                    if state:
                        val = state[0]
                        bval = state[1]
                        if bval == 0:
                            if val == 1:
                                button.turn_on()
                            else:
                                button.turn_off()
                        elif bval == 1:
                            if sblink == 0:
                                button.turn_on()
                            else:
                                button.turn_off()
                        elif bval == 2:
                            if fblink == 0:
                                button.turn_on()
                            else:
                                button.turn_off()
                    else:
                        button.turn_off()
                else:
                    button.turn_off()

    def on_track_list_changed(self):
        num_tracks = len(self.tracks_to_use())
        new_track_offset = self.track_offset()
        if new_track_offset >= num_tracks:
            new_track_offset = num_tracks - 1
            new_track_offset -= new_track_offset % self._track_banking_increment
        self._reassign_tracks()
        self.set_offsets(new_track_offset, self.scene_offset())

    def update(self):
        SessionComponent.update(self)
        self._bank_up_button.update()
        self._bank_down_button.update()
        self._bank_left_button.update()
        self._bank_right_button.update()

    def _bank_right(self):
        return self.set_offsets(self.track_offset() + self._track_banking_increment, self.scene_offset())

    def _bank_left(self):
        return self.set_offsets(max(self.track_offset() - self._track_banking_increment, 0), self.scene_offset())

    def bank_down(self):
        if self.is_enabled():
            newoff = max(0, self._scene_offset - 1)
            self.set_offsets(self._track_offset, newoff)

    def bank_up(self):
        if self.is_enabled():
            self.set_offsets(self._track_offset, self._scene_offset + 1)

    def bank_left(self):
        if self.is_enabled():
            self.set_offsets(max(0, self._track_offset - 1), self._scene_offset)

    def bank_right(self):
        if self.is_enabled():
            self.set_offsets(self._track_offset + 1, self._scene_offset)

    def _allow_updates(self):
        return True

    def disconnect(self):
        self._matrix = None
        self._mode_button = None
        SessionComponent.disconnect(self)